Qt信号和插槽混乱

时间:2014-01-17 21:31:53

标签: c++ qt signals-slots

我一直在阅读有关Qt信号和插槽的信息,我正在尝试让它工作,但直到现在还没有成功。我希望有人能指出我正确的方向 我有两个文件homeCommand.cppmessagelogcommand.cpp。我在QPlainTextEdit中有一个messagelogcommand.cpp对象,我想从homeCommand.cpp更新 我怎么能用信号和插槽做到这一点?正在调用我的信号,因为我的QDebug每秒打印一次,但小部件不会更新。

这就是我想要做的事情:

在MessageLogCommand.h中

class MessageLogCommand : public QWidget
{
    Q_OBJECT
public:
    explicit MessageLogCommand(QWidget *parent = 0);

    QLabel *homeLabel;
    QPlainTextEdit *messageLog;

public Q_SLOTS:
    void updateWidgets(const QString &text);

};

homeCommand.h

class homeCommand : public QWidget
{
    Q_OBJECT

Q_SIGNALS:
    void textChanged(const QString &text);

public:
    explicit homeCommand(QWidget *parent = 0);

public slots:
    void run(void);
    void getHealthStatusPacket(void);

homeCommand.cpp

homeCommand::homeCommand(QWidget *parent) : QWidget(parent)
{
    ...
    //Timer
    QTimer *timer = new QTimer(this);
    timer->setSingleShot(false);
    connect(timer, SIGNAL(timeout()), this, SLOT(run()));
    timer->start(1000);

    setLayout(layout);
}

void homeCommand::run(void)
{
    getHealthStatusPacket();
}

void homeCommand::getHealthStatusPacket(void)
{
    ...
    Q_EMIT textChanged("ZOMG");
}

在MessageLogCommand.cpp

 MessageLogCommand::MessageLogCommand(QWidget *parent) : QWidget(parent)
 {

    QGridLayout *layout = new QGridLayout;
    QWidget::setFixedHeight(600);

    //Sub-system Label
    homeLabel = new QLabel("GSS Message Log");
    QFont subsystemFont = homeLabel->font();
    subsystemFont.setPointSize(12);
    subsystemFont.setBold(true);
    homeLabel->setFont(subsystemFont);
    layout->addWidget(homeLabel, 0, 0);

    //Event Log
    messageLog = new QPlainTextEdit();
    messageLog->setFixedHeight(500);
    messageLog->setFixedWidth(600);
    layout->addWidget(messageLog, 2,0);

    setLayout(layout);
}

void MessageLogCommand::updateWidgets(const QString &text)
{
    qDebug() << "Here";
    messageLog->appendPlainText(text);
}

在main.cpp

MessageLogCommand s;
homeCommand m;

QObject::connect(&m, SIGNAL(textChanged(QString)), &s, SLOT(updateWidgets(QString)));

3 个答案:

答案 0 :(得分:1)

一个非常基本的例子是:

class MainClass:public QObject    //class must be derived from QObject!
{
   Q_OBJECT    //this macro must be in the class definition
               //so the moc compiler can generate the necessary glue code

   public:
       void doSomething() {
           ...
           Q_EMIT textChanged(someText);
       }

   Q_SIGNALS:
       void textChanged(const QString &text);
};

class SubClass:public QObject
{
   Q_OBJECT

   public Q_SLOTS:
       void onTextChanged(const QString &text) {    //do not inline
           //do something
       }
};

int main()
{
    QApplication a;

    MainClass m;
    SubClass s;
    QObject::connect(&m, SIGNAL(textChanged(QString)),
                     &s, SLOT(onTextChanged(QString)));  //const and & are removed from
                                                         //the arguments

    return a.exec();    //run the event loop
}

所以,有两件事很重要: 1.必须在从QObject派生的类中声明信号和槽 2.包含信号和槽声明的类必须将Q_OBJECT宏添加到类声明

为了简单起见:始终在头文件中声明包含信号或插槽的类(从不在.cpp文件中)。

答案 1 :(得分:0)

信号和广告位的一个非常好的起点是:http://woboq.com/blog/how-qt-signals-slots-work.html但官方Qt文档也是这样做的:http://qt-project.org/doc/qt-4.8/signalsandslots.html

基本上会发生什么:你声明了一些特殊的方法(信号和插槽),在编译阶段Qt生成额外的CPP文件,它们处理你的方法(moc)然后一切都被编译和链接在一起,最后当Qt或别人会发出一个信号,它会转到相应的位置。

答案 2 :(得分:-1)

我试着解释一下。

在main.h中你应该声明一个信号:

signals:
     void textChanged(const QString& text);

在messagelog.h中你应该声明一个插槽:

public slots:
     void updateWidgets(const QString& text);

在main.cpp中你应该发出这个信号:

void TheMethod() {
    emit this->textChanged("Your text/value");
}

在messagelog.cpp中你应该得到这个值:

// Note: Normalized signal/slot signatures drop the consts and references.
connect(&a, SIGNAL(textChanged(QString)), this, SLOT(updateWidgets(QString)));

void updateWidgets(const QString& text) {
   messageLog = new QPlainTextEdit();
   messageLog->setFixedHeight(500);
   messageLog->setFixedWidth(600);
   messageLog->setPlainText(text)
   layout->addWidget(messageLog, 2,0);
}

我认为它应该有效。

<强>更新 完整示例:https://dl.dropboxusercontent.com/u/29647980/test.zip