QtCreator C++ 在 main window 中创建线程
QtCreator C++ create thread in main window
我正在构建一个应用程序,它通过串行接口接收数据。所以我为串行处理实现了一个class,它可以成功地接收和发送数据。现在我尝试将数据移动到 UI,将其发送到控制台,但我需要一个线程,这似乎比我预期的要难。
所以我需要以某种方式定义一个线程并在创建 UserInterface 的开始时启动它,然后该线程应该轮询一个函数以获取新数据。我研究了创建一个线程并将其连接到回调函数,但它总是与创建一个继承自 QThread 的 class 有关,而我不能为 Main UI 做这件事。
我应该如何在 Main UI 中定义一个线程,然后我可以用它来轮询一个函数?
编辑: 按照建议,这里不需要线程,但我不知道如何在没有对象的情况下调用 class 中的函数。在主窗口 class 中,所有 UI 标签和按钮之类的东西都位于其中,我创建了一个用于串行通信的对象。在这个对象内部,当接收到新数据时调用中断。因此,例如,我可以将这些数据放入这个串行对象中,但我仍然需要以某种方式转发它们。
Edit2: 第一个实际可行的方法是实现一个计时器,它会定期调用一个更新函数。但是由于串行接收是中断驱动的,所以必须有一种回调方式,这样我就不需要轮询了。
如评论中所述,在此用例中最好不要使用线程,而是利用 Qt 事件循环和信号槽机制。这是 MainWindow 和 SerialReciver classes 的框架,以及它们如何在 main.cpp 中连接在一起。为简单起见,SerialReceiver class 仅在当前时间每秒发出一次信号,该信号将附加到主 window 中编辑字段的内容。
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPlainTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onSerialMessage(const QString &msg);
private:
QPlainTextEdit mTextField;
};
mainwindow.cpp:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
mTextField.setReadOnly(true);
setCentralWidget(&mTextField);
}
MainWindow::~MainWindow()
{
}
void
MainWindow::onSerialMessage(const QString &msg)
{
mTextField.appendPlainText(msg);
}
#endif // MAINWINDOW_H
serialreceiver.h:
#ifndef SERIALRECEIVER_H
#define SERIALRECEIVER_H
#include <QObject>
#include <QTimer>
class SerialReceiver : public QObject
{
Q_OBJECT
public:
explicit SerialReceiver(QObject *parent = nullptr);
signals:
void newMsg(const QString &msg);
public slots:
void onSerialReceived();
private:
QTimer mTimer;
};
#endif // SERIALRECEIVER_H
serialreceiver.cpp:
#include "serialreceiver.h"
#include <QDateTime>
SerialReceiver::SerialReceiver(QObject *parent) : QObject(parent)
{
mTimer.setInterval(1000);
mTimer.setSingleShot(false);
connect(&mTimer, &QTimer::timeout,this,&SerialReceiver::onSerialReceived);
mTimer.start();
}
void
SerialReceiver::onSerialReceived()
{
QDateTime now = QDateTime::currentDateTime();
emit newMsg(now.toString());
}
和main.cpp:
#include "mainwindow.h"
#include "serialreceiver.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SerialReceiver receiver;
MainWindow w;
QObject::connect(&receiver, &SerialReceiver::newMsg,
&w,&MainWindow::onSerialMessage);
w.show();
return a.exec();
}
我正在构建一个应用程序,它通过串行接口接收数据。所以我为串行处理实现了一个class,它可以成功地接收和发送数据。现在我尝试将数据移动到 UI,将其发送到控制台,但我需要一个线程,这似乎比我预期的要难。
所以我需要以某种方式定义一个线程并在创建 UserInterface 的开始时启动它,然后该线程应该轮询一个函数以获取新数据。我研究了创建一个线程并将其连接到回调函数,但它总是与创建一个继承自 QThread 的 class 有关,而我不能为 Main UI 做这件事。
我应该如何在 Main UI 中定义一个线程,然后我可以用它来轮询一个函数?
编辑: 按照建议,这里不需要线程,但我不知道如何在没有对象的情况下调用 class 中的函数。在主窗口 class 中,所有 UI 标签和按钮之类的东西都位于其中,我创建了一个用于串行通信的对象。在这个对象内部,当接收到新数据时调用中断。因此,例如,我可以将这些数据放入这个串行对象中,但我仍然需要以某种方式转发它们。
Edit2: 第一个实际可行的方法是实现一个计时器,它会定期调用一个更新函数。但是由于串行接收是中断驱动的,所以必须有一种回调方式,这样我就不需要轮询了。
如评论中所述,在此用例中最好不要使用线程,而是利用 Qt 事件循环和信号槽机制。这是 MainWindow 和 SerialReciver classes 的框架,以及它们如何在 main.cpp 中连接在一起。为简单起见,SerialReceiver class 仅在当前时间每秒发出一次信号,该信号将附加到主 window 中编辑字段的内容。
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPlainTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onSerialMessage(const QString &msg);
private:
QPlainTextEdit mTextField;
};
mainwindow.cpp:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
mTextField.setReadOnly(true);
setCentralWidget(&mTextField);
}
MainWindow::~MainWindow()
{
}
void
MainWindow::onSerialMessage(const QString &msg)
{
mTextField.appendPlainText(msg);
}
#endif // MAINWINDOW_H
serialreceiver.h:
#ifndef SERIALRECEIVER_H
#define SERIALRECEIVER_H
#include <QObject>
#include <QTimer>
class SerialReceiver : public QObject
{
Q_OBJECT
public:
explicit SerialReceiver(QObject *parent = nullptr);
signals:
void newMsg(const QString &msg);
public slots:
void onSerialReceived();
private:
QTimer mTimer;
};
#endif // SERIALRECEIVER_H
serialreceiver.cpp:
#include "serialreceiver.h"
#include <QDateTime>
SerialReceiver::SerialReceiver(QObject *parent) : QObject(parent)
{
mTimer.setInterval(1000);
mTimer.setSingleShot(false);
connect(&mTimer, &QTimer::timeout,this,&SerialReceiver::onSerialReceived);
mTimer.start();
}
void
SerialReceiver::onSerialReceived()
{
QDateTime now = QDateTime::currentDateTime();
emit newMsg(now.toString());
}
和main.cpp:
#include "mainwindow.h"
#include "serialreceiver.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SerialReceiver receiver;
MainWindow w;
QObject::connect(&receiver, &SerialReceiver::newMsg,
&w,&MainWindow::onSerialMessage);
w.show();
return a.exec();
}