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

时间:2018-06-21 09:26:55

标签: c++ multithreading qt qt5

我正在尝试为一个带有其计时器的新计时器的每个动作创建一个集合,用于开始一个动作的计时器。

如何在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;

1 个答案:

答案 0 :(得分:2)

多线程与计时器无关。 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();
}