如何在QtConcurrent::run中启动QTimer或为什么QVector<QTimer*>不起作用



我正在尝试为带有时间计数器的新计时器的每个操作创建一组用于启动动作的计时器。

如何在QtConcurrent::run中启动QTimer或为什么QVector不起作用

我试过这个,但写道 - 不是正确的函数调用:

for (int i =0; i < test_checkbox.length(); i++ )
{
if (Value == true)
{
if(test_checkbox[i]->isChecked() ==Value)
{
// timer->start(struc_mess_add.MS);  // work
QtConcurrent::run(timer->start(vector_struc_mess_add[i].MS),&timer);  // not work
}
} else {
qDebug() << "chekbocks:" << " False";
timer->stop();  
}
}

但是它被绑在的插槽上:

connect(timer, SIGNAL(timeout()), this, SLOT(KAN_minimal())); 

在头文件中:

QTimer *timer = new QTimer();  

已尝试通过矢量进行尝试。但它不会给出错误,也不会0_o工作。

timer = new QTimer();        // initialize the timer
vector_qtimer.append(timer);    // put the timer in the vector
vector_qtimer[i]->start(vector_struc_mess_add[i].MS);

在头文件中:

QTimer *timer  = new QTimer();  
QVector<QTimer*> vector_qtimer;

多线程与计时器无关。QtConcurrent 与计时器无关,它的实现没有事件循环,所以如果你尝试在QtConcurrent::run调用的代码中使用计时器 - 它将不起作用。当然,您可以在将来安排并发操作:

// Show a message ten seconds from now, without blocking the UI
QTimer::singleShot(10000, []{ QtConcurrent::run([]{ 
qDebug() << "The future is now.";
QThread::sleep(2); // block to demonstrate that the UI is unaffected
qDebug() << "Some time has passed";
}));

如果操作需要单次计时器,请使用QTimer::singleShot,然后无需手动跟踪计时器。

否则,计时器可以作为值保留在任何不需要复制或移动它们的容器中:

std::list<QTimer> timers;
std::array<QTimer, 10> timers;

如果计时器的数量动态变化,则使用std::list,如果计时器的数量恒定,则std::array使用计时器。

要遍历列表,不能使用整数索引,只能使用迭代器 - 但您仍然可以维护整数索引来访问相关数据:

int i = 0;
for (auto t = timers.begin(); t != timers.end(); ++i, ++t) {
if (checkboxes[i]->isChecked())
t->start();
}

也可以将有关计时器的信息直接添加到连接中 - 但最好将 UI 和逻辑分离。这假设了很多关于你想做什么 - 你的方法是否必要或不太复杂,这一点并不明显:

class Controller : public QObject {
Q_OBJECT
int handleCount = 0;
public:
QVariant addSomething() {
struct 
auto *timer = new QTimer(this);
timer->setObjectName(QStringLiteral("ctlTimer%1").arg(handleCount));
handleCount++;
...
return QVariant::fromValue(timer);
}
void setEnabled(const QVariant &h, bool val) {
auto *timer = qvariant_cast<QTimer*>(h);
...
}
);
class UI : public QWidget {
Q_OBJECT
QVBoxLayout m_layout{this};
QPushButton m_add{"Add"};
std::list<QCheckBox> m_checkboxes;
public:
UI(QWidget *parent = {}) : QWidget(parent) {
m_layout.addWidget(&m_add);
connect(&m_add, &QPushButton::clicked, this, &UI::add);
}
Q_SIGNAL void add();
Q_SIGNAL void toggled(const QVariant &, bool);
void addSomething(const QVariant &handle) {
m_checkboxes.emplace_back(QStringLiteral("Checkbox %1").arg(m_checkboxes.size()+1));
auto *cb = &m_checkboxes.back();
layout()->addWidget(cb);
connect(cb,  &QCheckBox::toggled, [=](bool val){ emit toggled(handle, val); });
}
};

现在UIController被解耦,它们被组合成例如main

int main(int argc, char *argv[]) {
QApplication app(argc, argv);
Controller ctl;
UI ui;
connect(&ui, &UI::add, [&]{ ui.addSomething(ctl.addSomething()); });
connect(&ui, &UI::toggled, &ctl, &Controller::setEnabled);
ui.show();
return app.exec();
}

最新更新