我想创建一个工作线程,该线程将每隔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();
答案 0 :(得分:2)
这很简单:
您的计算是在QObject派生的类中完成的
更新是通过该对象中的信号发布的。
计算是在10-20毫秒的小块中完成的。
计算是从持续时间为零的计时器触发的-它不是计时器,而是一种检测线程中事件循环空闲状态的方法。
更新是通过1秒计时器触发的。
该类可以在任何线程上运行-甚至可以在GUI线程上运行,但是会使它的响应性降低一些(但一点也不无响应)。
您通常会实例化该类,开始计算,然后将其移至专用线程。