0

我正在尝试使用 Qt 制作一个简单的合成器。当您左键单击一个键但没有播放声音时,应该会播放一个音符。我试图寻找解决问题的方法,但没有找到任何有用的方法。由于我对 Qt 还很陌生,我认为问题在于我对框架的工作原理缺乏充分的了解,但我根本无法弄清楚为什么声音不会播放。

我已经设法从 main.cpp 发出声音,并在代码中进一步包含了播放声音和不播放声音时的示例。

希望我已经很好地提出了我的问题,并提前感谢。

//key.h
#ifndef KEY_H
#define KEY_H

#include <QGraphicsRectItem>
#include <QObject>
#include <QKeyEvent>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
#include <QBrush>
#include <QMediaPlayer>

enum Tune {A, B, C,  D, E, F,  G, ASS, BESS, DESS, ESS, GESS, MUTE}; // Key  tune

class Key : public QObject, public QGraphicsRectItem {
    Q_OBJECT
public:
    Key(Tune t=MUTE);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    void paintPlayedKey();
    void resetPaintedKey();
    void setTone();
    QMediaPlayer* getTone() {return tone;}
    Tune getTune() {return tune;}
private:
    Tune tune;
    QMediaPlayer *tone;
};

#endif // KEY_H

//key.cpp
#include "key.h"

void Key::paintPlayedKey()
{
    this->setBrush(* new QBrush(Qt::blue));
}

void Key::resetPaintedKey()
{
    if(tune < 7)
        this->setBrush(* new QBrush(Qt::white));
    else
        this->setBrush(* new QBrush(Qt::black));
}


void Key::setTone() // Sets sounds to tune
{

    if(tune == 0)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/a.wav"));
    else if (tune == 1)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/b.wav"));
    else if (tune == 2)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/c.wav"));
    else if (tune == 3)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/d.wav"));
    else if (tune == 4)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/e.wav"));
    else if (tune == 5)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/f.wav"));
    else if (tune == 6)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/g.wav"));
    else if (tune == 7)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/ab.wav"));
    else if (tune == 8)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/bb.wav"));
    else if (tune == 9)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/db.wav"));
    else if (tune == 10)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/eb.wav"));
    else if (tune == 11)
        tone->setMedia(QUrl("qrc:/keys/Pianosounds/TheKeys/gb.wav"));
}

Key::Key(Tune t)
{
    tune = t;
    tone = new QMediaPlayer();
    setTone();
}

void Key::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    //Not sure if we wanna do anything here
}

void Key::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    //play tune
    if (event->buttons() == Qt::LeftButton) {
           qDebug() << "Pressed";
           paintPlayedKey();

           if(tone->state() == QMediaPlayer::PlayingState) {
               tone->setPosition(0);
               qDebug() << "Have played?";
           }
           else if (tone->state() == QMediaPlayer::StoppedState) {
               qDebug() << "Should play?"; // Well it doesn't :-)
               tone->play();
           }
       }
}

void Key::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    //stop playing tune
    resetPaintedKey();
    tone->stop();
}


//main.cpp    
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QBrush>
#include <QMediaPlayer>
#include <QTimer>
#include <iostream>
#include <vector>

#include "mainwindow.h"
#include "key.h"

using namespace std;

const int W_KEY_H = 150; // White Key width and height
const int W_KEY_W = 50;
const double B_KEY_H = 150 * 2/3; // White Key width and height
const double B_KEY_W = 50/2;

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // create a scene
    QGraphicsScene *scene = new QGraphicsScene();

    // Create white keys of synth
    Tune a = A, b = B, c = C, d = D, e = E, f = F, g = G;
    Key *a1 = new Key(a);
    Key *b1 = new Key(b);
    Key *c1 = new Key(c);
    Key *d1 = new Key(d);
    Key *e1 = new Key(e);
    Key *f1 = new Key(f);
    Key *g1 = new Key(g);

    vector<Key*> whites = {a1, b1, c1, d1, e1, f1, g1};

    int x = 0;
    for(int i = 0; i < whites.size(); i++, x+=W_KEY_W)
        whites[i]->setRect(x, 0, W_KEY_W, W_KEY_H);

    // add the keys to the scene
    for(int i = 0; i < whites.size(); i++)
        scene->addItem(whites[i]);

    // focus keys
    for(int i = 0; i < whites.size(); i++) {
        whites[i]->setFlag(QGraphicsItem::ItemIsFocusable);
        whites[i]->setFocus();
    }

    // Create black keys of synth
    Tune ass = ASS, bess = BESS, dess = DESS, ess = ESS, gess = GESS;
    Key *ass1 = new Key(ass);
    Key *bess1 = new Key(bess);
    Key *dess1 = new Key(dess);
    Key *ess1 = new Key(ess);
    Key *gess1 = new Key(gess);
    Key *ass2 = new Key(ass);

    vector<Key*> blacks = {ass1, bess1, dess1, ess1, gess1, ass2};

    // For now...
    ass1->setRect(a1->rect().x() - B_KEY_W/(double)2, 0, B_KEY_W, B_KEY_H);
    bess1->setRect(b1->rect().x() - B_KEY_W/(double)2, 0, B_KEY_W, B_KEY_H);
    dess1->setRect(d1->rect().x() - B_KEY_W/(double)2, 0, B_KEY_W, B_KEY_H);
    ess1->setRect(e1->rect().x() - B_KEY_W/(double)2, 0, B_KEY_W, B_KEY_H);
    gess1->setRect(g1->rect().x() - B_KEY_W/(double)2, 0, B_KEY_W, B_KEY_H);
    ass2->setRect(g1->rect().x() + g1->rect().width() - B_KEY_W/(double)2,     0, B_KEY_W, B_KEY_H); // Nödlösning

    //paint
    for(int i=0; i<blacks.size(); i++)
        blacks[i]->setBrush(* new QBrush(Qt::black));

    // add the keys to the scene
    for(int i = 0; i < blacks.size(); i++)
        scene->addItem(blacks[i]);

    // focus keys
    for(int i = 0; i < blacks.size(); i++) {
        blacks[i]->setFlag(QGraphicsItem::ItemIsFocusable);
        blacks[i]->setFocus();
    }

    // add a view
    QGraphicsView *view = new QGraphicsView(scene);

    //show view
    view->show();
    //view->setFixedSize(800, 600);
    //scene->setSceneRect(0, 0, 800, 600);

    // Sound plays
    QMediaPlayer *test = new QMediaPlayer();
    test->setMedia(QUrl("qrc:/sounds/Pianosounds/TheKeys/a.wav"));
    test->play();

    // doesn't play
    c1->getTone()->play();

    return app.exec();
}
4

0 回答 0