在单独的线程中使用QTimer的规范方法

时间:2018-10-07 17:56:40

标签: c++ multithreading qt qthread qtimer

我想创建一个工作线程,该线程将每隔1秒更新一次QTWidget(考虑到数字时钟或进度条更新程序,它可能是一个更好的类比)。

我的应用程序特定于航空电子设备,可在飞行过程中以1秒的间隔计算飞行路径上的飞行跟踪信息并定期更新地图或其他QT小部件(我想您可以将其视为一种进步) bar-在我的情况下,进度条可以用地图或表格小部件代替)。该线程可能需要大约10-20秒来计算整个飞行数据-(但是几乎可以立即获得其第一个结果)-这些结果需要每隔1秒发送到GUI来更新飞机的位置在地图上。

关于合并更新工作线程的计时器的正确和错误方法有很多困惑。我发现的最佳知识来源是发起Multithreading with Qt - Giuseppe D’Angelo的QtCon对话-似乎首选的方法是让工作器QObject不继承QThread并运行计时器在它自己的事件处理程序中-但是将工作线程移动到我不太了解的另一个线程上有很多困惑,我正在寻找有关如何正确执行此操作的规范建议。在Lambda中这样做是理想的,因为我可以使逻辑和线程保持相对隔离,这将是理想的。

我正在寻找是否有人可以将我指向类似示例的方向(尤其是如果它使用现代Lambda)。我当前正在使用QT 5.11.2。

我的工作对象(包含QTimer如下):

class SimulatedFlightWorker : public QObject
{
    Q_OBJECT
public:
    explicit  SimulatedFlightWorker()
        : mpMMRFlightData{}
    {}
public slots:
    // worker thread slot that computes the mpMMRFlightData
    void importSimulatedFlight(
        const QString& fileName,
        const int aPlaybackSpeed);
    void updateGUI(int secondsElapsed);
signals:
    // every second during the flight we need to send a new MMR
    // record to the GUI - to display on a spreadsheet or google map
    void updateFlightData(const MMRTimedRecord& rMMRRecord);

    // this is effectively when the worker thread is done
    void flightCompleted();
private:
    QTimer mTimer;
    // the 
    std::unique_ptr<MMRFlightData> mpMMRFlightData;
};

这是我设置信号和插槽的代码(尚不可用)

// Experimental worker model adapted from YouTube tutorial
// by Giuseppe di Angelo https://www.youtube.com/watch?v=BgqT6SIeRn4
auto thread = new QThread;
auto worker = new SimulatedFlightWorker;


connect(thread, &QThread::started, worker, &SimulatedFlightWorker::importSimulatedFlight);
connect(worker, &SimulatedFlightWorker::flightCompleted, thread, &QThread::quit);
connect(thread, &QThread::finished, worker, &SimulatedFlightWorker::deleteLater);

worker->moveToThread(thread);
thread->start();

1 个答案:

答案 0 :(得分:2)

这很简单:

  1. 您的计算是在QObject派生的类中完成的

  2. 更新是通过该对象中的信号发布的。

  3. 计算是在10-20毫秒的小块中完成的。

  4. 计算是从持续时间为零的计时器触发的-它不是计时器,而是一种检测线程中事件循环空闲状态的方法。

  5. 更新是通过1秒计时器触发的。

该类可以在任何线程上运行-甚至可以在GUI线程上运行,但是会使它的响应性降低一些(但一点也不无响应)。

您通常会实例化该类,开始计算,然后将其移至专用线程。