使用qt写一个程序,要求多线程绘制动态曲线图,将绘图操作放在一个独立的线程中运行,避免阻塞 UI 线程
时间: 2024-03-13 18:45:20 浏览: 148
Qt实现动态曲线图+文本数据的实时显示
3星 · 编辑精心推荐
好的,下面是一个简单的示例程序,演示了如何在 Qt 中使用多线程绘制动态曲线图:
```
#include <QtWidgets>
#include <QtCore>
class Worker : public QObject
{
Q_OBJECT
public:
Worker(QObject *parent = nullptr) : QObject(parent) {}
signals:
void dataReady(QVector<double> data);
public slots:
void doWork() {
QVector<double> data;
for (int i = 0; i < 1000; ++i) {
data.append(qSin(i / 10.0));
}
emit dataReady(data);
}
};
class Plotter : public QWidget
{
Q_OBJECT
public:
Plotter(QWidget *parent = nullptr) : QWidget(parent) {}
public slots:
void setData(QVector<double> data) {
m_data = data;
update();
}
protected:
void paintEvent(QPaintEvent *event) override {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(Qt::blue);
for (int i = 1; i < m_data.size(); ++i) {
painter.drawLine(i - 1, height() / 2 * (1 - m_data[i - 1]), i, height() / 2 * (1 - m_data[i]));
}
}
private:
QVector<double> m_data;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
m_workerThread.start();
m_worker.moveToThread(&m_workerThread);
connect(&m_workerThread, &QThread::finished, &m_worker, &QObject::deleteLater);
connect(this, &MainWindow::startWork, &m_worker, &Worker::doWork);
connect(&m_worker, &Worker::dataReady, &m_plotter, &Plotter::setData);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(&m_plotter);
QWidget *central = new QWidget;
central->setLayout(layout);
setCentralWidget(central);
}
~MainWindow() {
m_workerThread.quit();
m_workerThread.wait();
}
public slots:
void start() {
emit startWork();
}
private:
QThread m_workerThread;
Worker m_worker;
Plotter m_plotter;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
QTimer::singleShot(0, &w, &MainWindow::start);
return a.exec();
}
#include "main.moc"
```
这个程序中,我们创建了一个 `Worker` 类,用于在后台线程中生成数据,在数据生成完毕后通过信号通知主线程。主线程中创建了一个 `Plotter` 类,用于在 UI 界面中绘制动态曲线图。在主线程中,我们将 `Worker` 对象移动到一个独立的线程中运行,并通过信号和槽连接进行数据传递和绘图操作。程序启动后,我们通过一个定时器触发 `start` 槽函数,开始运行后台线程生成数据并刷新 UI 界面。
需要注意的是,为了避免多线程带来的数据竞争问题,我们需要使用线程间的信号和槽机制进行数据传递。同时,为了避免线程间的数据拷贝,我们使用了 `QVector` 类型,它支持在多个线程间进行数据共享。
阅读全文