Q_EMIT无法通过连接插槽工作,仅适用于QTimer插槽

时间:2014-03-13 18:57:48

标签: qt signals-slots

我正在尝试发出一个信号,如果插槽连接到QTimer,则该信号有效。但是,如果插槽连接到QPushButton,则它不起作用。例如,我有一个run()函数,它连接到1秒QTimer。 run()函数包含Q_EMIT textChanged("Test")此信号按预期工作。但是,如果我有一个连接到插槽的QPushButton,它也包含Q_EMIT textChanged("Test")没有任何反应......为什么会这样???

#include <QApplication>
#include <QVBoxLayout>
#include <QPlainTextEdit>
#include <QTabWidget>
#include <QTimer>
#include <QPushButton>

class Counter : public QWidget
{
   Q_OBJECT
public:
   explicit Counter(QWidget *parent = 0) : QWidget(parent) {
      QTimer *timer = new QTimer(this);
      connect(timer, SIGNAL(timeout()), SLOT(run()));
      timer->start(1000);

      QVBoxLayout *layout = new QVBoxLayout(this);
      QPushButton *OK = new QPushButton("OK");
      connect(OK, SIGNAL(clicked()), SLOT(OKalarmLimits()));
      layout->addWidget(OK);
   }
   Q_SIGNAL void textChanged(const QString &text);
   Q_SLOT void run() { Q_EMIT textChanged("Run - Counter"); }
   Q_SLOT void OKalarmLimits() { Q_EMIT textChanged("Button Clicked"); }
};

class MainWindow : public QWidget {
   Q_OBJECT
   QPlainTextEdit *box;
public:
   explicit MainWindow(QWidget *parent = 0) : QWidget(parent) {
      QVBoxLayout * layout = new QVBoxLayout(this);

      box = new QPlainTextEdit();
      box->setMaximumHeight(400);
      box->setMinimumWidth(400);
      layout->addWidget(box);

      QTabWidget *tabWidget = new QTabWidget;
      tabWidget->addTab(new Counter(), tr("Counter"));
      layout->addWidget(tabWidget);

      QTimer *timer = new QTimer(this);
      connect(timer, SIGNAL(timeout()), SLOT(run()));
      timer->start(1000);
   }
   Q_SLOT void updateWidgets(const QString &t) { box->appendPlainText(t); }
   Q_SLOT void run() { box->appendPlainText("Run - Window"); }
};

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   MainWindow s;
   Counter m;
   s.show();
   s.connect(&m, SIGNAL(textChanged(QString)), SLOT(updateWidgets(QString)));
   return a.exec();
}

#include "main.moc"

1 个答案:

答案 0 :(得分:2)

这真的很容易。有两个不同的计数器,您将连接到错误的计数器。

Counter中的main()实例,即您连接的show()实例,从未显示过(毕竟您不会调用其tabWidget->addTab(new Counter(), tr("Counter"));方法!)。您需要连接到此行中创建的实例:MainWindow()

一种解决方案是在 Counter * counter = new Counter(); QObject::connect(counter, SIGNAL(textChanged(QString)), SLOT(updateWidgets(QString))); QTabWidget *tabWidget = new QTabWidget; tabWidget->addTab(counter, tr("Counter")); layout->addWidget(tabWidget,1,0); 中进行连接:

main()

这也说明了为什么最小的例子应该是最小的。如果您继续致力于最小化,您已经发现了该错误。从本质上讲,你可以删除Counter m; QObject::connect(&m, SIGNAL(textChanged(QString)), &s,SLOT(updateWidgets(QString))); 下面的行而不改变行为:这将是一个死的赠品,你想到的计数器不是那个。

{{1}}