Qt信号メカニズム


この文章があなたに役に立つと思ったら、足跡を残してください.
Qt信号スロットメカニズムは複雑であるが,使用は簡単である.以下の内容は、個人が遭遇したいくつかの状況をまとめた経験であり、原理が絶対的に正しいとは保証されていませんが、このように使用するのは間違いありません.
問:信号とスロットは一対一でしか対応できませんか?
答え:いいえ、
複数の信号が1つのスロットに対応するもよく、connect multi-signals to one-slotであってもよい.
1つの信号が複数のスロットに対応していてもよく、connect one-signal to multi-slotsであってもよい
1つの信号が1つの信号に対応する、connect one-signal to one-signalであってもよい.
問:信号をカスタマイズできる条件は何ですか.
答え:一つの条件.あなたが継承したベースクラスはQObjectから継承しなければなりません.QObjectから派生していないクラスが継承されている場合は、信号をカスタマイズすることはできません.
はっきりしないのは次のQtクラス図を見ることができて、一目瞭然です
質問:QObjectから派生しないクラスを継承した場合、信号メカニズムを使用する必要がありますか?
答え:マルチ継承で解決
問:どのようにして自分の信号を定義しますか?
答え:以下のステップに分けます
(1)自分が引き継いだクラスがQObjectから派生したかどうかを確認し,クラス図やヘルプマニュアルを見てもよい.
(2)クラスヘッダにQ_OBJECT定義を加えていないかを確認し,なければコンパイルできない.
(3)signalsを用いて後の内容が信号宣言であることを宣言する
(4)信号はvoid fun(type)の形式で宣言され、typeは信号送信時のデータ型である.信号間はデータを伝達することができる.
(5)通常信号と同様にconnect関数を用いて信号スロットをリンクする必要があるが,信号がいつ送信されるかは独自の決定が必要である.
(6)信号を使用する必要がある場所でemitを用いて信号を送信する.
上記の内容が読めないと思ったら、大丈夫です.例を挙げてみてください.
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QtGui>
#include <QtCore>


namespace Ui {
    class Dialog;
}

class Dialog : public QDialog /*  (1),  OObject      */
{
    Q_OBJECT   /*  (2),    */

    public:
        explicit Dialog(QWidget *parent = 0);
        ~Dialog();

        void stringchange(QString newstr);  /*          ,                  */

signals:  /*  (3),           */
        void sigtest(QString);  //  (4),        ,     void,     QString

        public slots:
            void acceptstr(QString);    /*        */

    private:
        Ui::Dialog *ui;
        QString str;
};


#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    str = "hello";
    //    sleep(3);
    //    stringchange("hello world");
    connect(this, SIGNAL(sigtest(QString)), this, SLOT(acceptstr(QString)));    //  (5),        
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::stringchange(QString newstr)
{
    if (newstr != str)
    {
        str = newstr;
        emit sigtest(newstr);   //  (6),      sigtest  ,  newstr      
    }
}

void Dialog::acceptstr(QString newstr)  //          QString  ,            
{
    QMessageBox::about(this, "change str", newstr); //       
}
              。

 :            QObject  ,               ?
 :        ,       ,         。      Q_Object     。
        ,    
(1)            ,     QObject
(2)           。
      
#ifndef BBB_H
#define BBB_H

#include <QObject>

class bbb : public QObject  /*(1),   QObject,           。*/
{
    Q_OBJECT
    public:
        explicit bbb(QObject *parent = 0);

signals:
        void isDead();

        public slots:

};

#endif // BBB_H

#include "bbb.h"

bbb::bbb(QObject *parent) :
    QObject(parent)
{
}

#ifndef AAA_H
#define AAA_H

#include <QGraphicsItem>
#include <QtGui>
#include "bbb.h"

class aaa : public QGraphicsItem, public bbb /*(2),      bbb ,          */
{
    public:
        explicit aaa();
        QRectF boundingRect() const;
        void  paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);


        public slots:
    private:
            QTimer *timer;

};

#endif // AAA_H

#include "aaa.h"

aaa::aaa()
{
    setPos(100,100);

    timer = new QTimer;
    timer->start(1000);
    connect(timer, SIGNAL(timeout()), this, SIGNAL(isDead()));
}

QRectF aaa::boundingRect() const
{
    return QRectF(-100, -100, 200, 200);
}

void aaa::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QRectF rec = boundingRect();
    painter->fillRect(rec, Qt::red);
}