У меня почему-то возникает ощущение, что OP собирается «чрезмерно спроектировать» то, что может быть на самом деле довольно простым.
Я сделал MCVE , чтобы продемонстрировать это.
testQTimerStartStop.cc
:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
// prepare application
QApplication app(argc, argv);
QTimer qTimer;
qTimer.setInterval(1000);
// setup GUI
QWidget qWinMain;
qWinMain.setWindowTitle(QString::fromUtf8("QTimer Test"));
QFormLayout qForm;
QSpinBox qEditTimer;
qEditTimer.setRange(0, 30);
qForm.addRow(
QString::fromUtf8("Count down:"),
&qEditTimer);
QPushButton qBtnStart(QString::fromUtf8("Start"));
qForm.addRow(&qBtnStart);
QPushButton qBtnStop(QString::fromUtf8("Stop"));
qForm.addRow(&qBtnStop);
qWinMain.setLayout(&qForm);
qWinMain.show();
// set initial states
qEditTimer.setValue(10);
auto updateBtns = [&]() {
const int count = qEditTimer.value();
qBtnStart.setEnabled(!qTimer.isActive() && count > 0);
qBtnStop.setEnabled(qTimer.isActive());
};
updateBtns();
// install signal handlers
QObject::connect(&qTimer, &QTimer::timeout,
[&]() {
qEditTimer.setValue(qEditTimer.value() - 1); // count down
});
QObject::connect(&qEditTimer, (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
[&](int count) {
if (count <= 0) qTimer.stop();
updateBtns();
});
QObject::connect(&qBtnStart, &QPushButton::clicked,
[&](bool) { qTimer.start(); updateBtns(); });
QObject::connect(&qBtnStop, &QPushButton::clicked,
[&](bool) { qTimer.stop(); updateBtns(); });
// runtime loop
return app.exec();
}
testQTimerStartStop.pro
:
SOURCES = testQTimerStartStop.cc
QT += widgets
Сборка и запуск:
$ qmake-qt5 testQTimerStartStop.pro
$ make && ./testQTimerStartStop
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQTimerStartStop.o testQTimerStartStop.cc
g++ -o testQTimerStartStop.exe testQTimerStartStop.o -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
Qt Version: 5.9.4
![Snapshot of testQTimerStartStop (animated)](https://i.stack.imgur.com/QHSuK.gif)
Перемещение QTimer
в другой поток добавило бы много накладных расходов.Любой доступ к QTimer
должен был
- произойти до запуска потока или
- для защиты мьютексом или
- через сигналы (с
Qt::QueueConnection
).
Я на мгновение подумал, чтобы адаптировать свой образец соответственно, но вскоре осознал необходимые усилия и остановился.ИМХО, я бы не рекомендовал это, если нет веских причин для этого.
Пожалуйста, учтите, что: Приложение, которое находится под большой нагрузкой и вызывает значительные задержки в выдаче сигнала тайм-аута, вероятно, также не в состояниидля обработки событий тайм-аута, которые отправляются другим потоком во времени.