Frage

I am trying to emit a signal, which works if the slot if hooked up to a QTimer. However if the slot is hooked up to a QPushButton for example, it doesn't work. For example, I have a run() function that it connected to a 1 second QTimer. The run() function contains Q_EMIT textChanged("Test") This signal works as expected. However, if I have a QPushButton connected to a slot, which also contains Q_EMIT textChanged("Test") nothing happens...why is this???

#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"
War es hilfreich?

Lösung

It's real easy. There are two different counters, and you're connecting to the wrong one.

The Counter instance in main(), the one that you connect to, is never shown (you don't call its show() method after all!). You need to connect to the instance that is created in this line: tabWidget->addTab(new Counter(), tr("Counter"));

One solution would be do the connection in 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);

This also illustrates why minimal examples should really be minimal. Were you to continue working on minimization, you'd have found the bug. Essentially, you can delete the lines below from main() without any change in behavior: this would be a dead giveaway that the counter you think of is not the one.

Counter m;
QObject::connect(&m, SIGNAL(textChanged(QString)), &s,SLOT(updateWidgets(QString)));
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top