【发布时间】:2015-01-10 10:51:54
【问题描述】:
您好,我在通过线程更新 ui 时遇到问题。 代码工作正常,但问题是当我想移动我的窗口时,你知道那一刻 ui 线程将停止更新。我的线程将值发送到导致错误的停止线程。 我不知道如何解决这个问题。
这是我的线程代码标题:
#ifndef READERTHREAD_H
#define READERTHREAD_H
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QThread>
class readerThread : public QThread
{
Q_OBJECT
public:
explicit readerThread(QObject *parent = 0);
void run();
bool stop = false;
QByteArray port_input;
QByteArray payload;
quint8 starter_symbol = 0;
quint8 message_length = 0;
quint8 message_ID = 0;
readerThread *thread;
signals:
void updated(QByteArray , quint8);
private:
QSerialPort *serial;
};
#endif // READERTHREAD_H
我的线程.cpp:
#include "readerthread.h"
#include <QtCore>
readerThread::readerThread(QObject *parent) :
QThread(parent)
{
serial = new QSerialPort(this);
foreach (const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts())
serial->setPortName(serialPortInfo.portName());
serial->setBaudRate(QSerialPort::Baud115200);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->setStopBits(QSerialPort::OneStop);
// serial->setReadBufferSize(8192);
serial->open(QIODevice::ReadOnly);
serial->errorString();
}
void readerThread::run()
{
while(serial->isOpen())
{
port_input.append(serial->readAll());
if(port_input.count() >= 150)
{
starter_symbol = port_input.indexOf(254);
if((port_input.at(starter_symbol + 3) == 01) && (port_input.at(starter_symbol + 4) == 01))
{
message_length = port_input.at(starter_symbol + 1);
message_ID = port_input.at(starter_symbol + 5);
payload = port_input.mid(starter_symbol + 6 , message_length);
port_input.remove(starter_symbol , message_length + 8);
emit updated(payload , message_ID);
}
port_input.remove(0 , starter_symbol);
}
}
}
这里是我的 mainwindow.cpp :
struct mavlink_attitude_t
{
/// <summary> Timestamp (milliseconds since system boot) </summary>
quint32 time_boot_ms;
/// <summary> Roll angle (rad, -pi..+pi) </summary>
float roll;
/// <summary> Pitch angle (rad, -pi..+pi) </summary>
float pitch;
/// <summary> Yaw angle (rad, -pi..+pi) </summary>
float yaw;
/// <summary> Roll angular speed (rad/s) </summary>
float rollspeed;
/// <summary> Pitch angular speed (rad/s) </summary>
float pitchspeed;
/// <summary> Yaw angular speed (rad/s) </summary>
float yawspeed;
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
thread = new readerThread(this);
connect(thread , SIGNAL(updated(QByteArray,quint8)) , this , SLOT(onUpdate(QByteArray,quint8)));
thread->start();
}
void MainWindow::onUpdate(QByteArray payload , quint8 ID)
{
mavlink_attitude_t data;
memcpy(&data,payload.data(),sizeof(mavlink_attitude_t));
ui->timebootms->setText(QString::number(data.time_boot_ms));
ui->roll->setText(QString::number(data.roll));
ui->pitch->setText(QString::number(data.pitch));
ui->yaw->setText(QString::number(data.yaw));
ui->rollspeed->setText(QString::number(data.rollspeed));
ui->pitchspeed->setText(QString::number(data.pitchspeed));
ui->yawspeed->setText(QString::number(data.yawspeed));
}
【问题讨论】:
-
您可以尝试强制连接为 Qt::QueuedConnection (这应该已经自动完成)。不确定如果没有事件循环,您的线程信号是否会正常。可以尝试创建一个在本机 QThread(信号槽支持)中运行的线程对象,或者只使用 QtConcurrent
-
感谢您的宝贵时间。没有事件循环是什么意思?
-
您的
connect具有默认的最后一个参数 (Qt::AutoConnection)。这意味着在主线程上调用onUpdate(窗口分配给主线程)。因此,请确认您确定问题的根源是什么。 -
感谢@Mark R 抽出宝贵时间,是的,我确定问题就是我所说的。我想知道是否有任何方法可以在某种情况下暂停线程并在此之后恢复它?
标签: c++ multithreading qt qtserialport qtwidgets