Qt中有串口设施吗?
如果没有,你建议使用哪个跨平台(理想)库(用于处理串口,可能还有其他I/O端口)?
我正在使用QtSerialPort库通过USB与虚拟COM端口通信.COM端口返回数据并在使用QtSerialPort给出的示例项目进行测试时正常工作,但是当我将其作为项目的一部分运行时失败.
我检查了实例化链和导致QtSerialPort被实例化的线程,并发现了一些有点奇怪的东西.结果如下.
main()
MainWindow (Thread 0xbf8dbe0) // Thread "A"
HardwareManager (Thread 0xbf8dbe0) // Thread "A"
QSerialPort (Thread 0xbfb95f0) // Thread "B" !?
Run Code Online (Sandbox Code Playgroud)
在我的代码中,main()函数实例化一个MainWindow,MainWindow又实例化一个HardwareManager并将其存储为私有变量.当实例化HardwareManager时,它还实例化QSerialPort实例,以便它可以正确地与COM端口通信.
但是,您会注意到我的QSerialPort位于与父对象不同的线程中,以及它的父对象(它位于线程B中,而两个祖先都位于线程A中).我认为这个其他线程导致我的信号/插槽失败.如果我是dumpObjectInfo,它会将我的信号/插槽列为正在设置,但事件永远不会触发.
this->serial = new QSerialPort();
connect(this->serial, SIGNAL(readyRead()), this, SLOT(readSerialData());
Run Code Online (Sandbox Code Playgroud)
以上是我用来创建新串行端口并将其连接到正确插槽的代码.实际的波特率,奇偶校验和数据/停止位配置单独发生(并且正常工作,如QtSerialPort提供的示例应用程序中所测试).
有没有人知道为什么这个特定的对象(QSerialPort实例)在另一个线程中被实例化?我试过"moveToThread"来切换线程关联,但似乎没有任何效果.
编辑: 以下是调用链中的相关代码:
// main()
QApplication a(argc, argv)
MainWindow window = new MainWindow(); // [1]
MainWindow.show();
return a.exec();
// MainWindow::MainWindow() [1]
this->toolController = new QtToolController(this);
HardwareManager *manager = new HardwareManager(this->toolController); // [2]
// HardwareManager::HardwareManager() [2]
this->serial …
Run Code Online (Sandbox Code Playgroud) 我从串口读取的数据(在Qt中,使用QtSerialPort/QSerialPort)由换行符'\n'分隔并返回'\ r'字符,这是我打算查看它进行解析的方式.行长可能很长,但很容易从每行的格式中提取数据.
//signal/slot connection on readyRead() is as follows:
connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
Run Code Online (Sandbox Code Playgroud)
其中readData()定义为:
void MainWindow::readData()
{
//As mentioned below, which I will reiterate, I have already tried the addition of
// canReadLine():
if (serial->canReadLine()){
QByteArray data = serial->readLine();
//QByteArray allData = serial->readAll();
parseSerialBytes(data);
//console->putData(data);
//console->putData(alldata);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,与QIODevice :: readAll()相比,该QIODevice::readLine()
函数非常慢,并且明显阻止数据以全频率接收
有人可以解释如何正确使用该readLine()
功能,所以我不必循环readAll()
进入QByteArray
解析每一行?我使用"终端"Qt Widgets示例来创建此异步串行端口读取功能.
在此先感谢 - 这似乎是我在这里尚未看到的常见问题.
我通过串口向设备发送(写入)字节.我正在使用QSerialPort(http://qt-project.org/wiki/QtSerialPort)模块来实例化设备IO支持.当我向INSTEON调制解调器(串行)发送消息时,在读取我的消息时,设备会发回我的消息副本+ 0x06(ACK Byte),然后是状态消息.
我使用DockLight(http://www.docklight.de/)测试了我的消息.我发送以下消息来查询设备的状态:
02 62 1D E9 4B 05 19 00
Run Code Online (Sandbox Code Playgroud)
使用Docklight,我收到回复:
02 62 1D E9 4B 05 19 00 06 02 50 20 CB CF 1E DA F7 21 00 FF
Run Code Online (Sandbox Code Playgroud)
返回的消息准确表明了我期望的设备是什么.如果关闭,如果设备关闭,调制解调器将在最后一个字节位置发回0x00.现在,我的问题 - 我必须正确设置我的功能才能发送然后接收响应字节.我尝试了很多不同的示例和配置,目前我正在使用以下内容:
设置信号槽连接:
QObject::connect(&thread, SIGNAL(sendResponse(QByteArray)),
this, SLOT(handleResponse(QByteArray)));
QObject::connect(&thread, SIGNAL(error(QString)),
this, SLOT(processError(QString)));
QObject::connect(&thread, SIGNAL(timeout(QString)),
this, SLOT(processTimeout(QString)));
Run Code Online (Sandbox Code Playgroud)
用于迭代设备QList的函数.如果设备是所需类型("Light"),那么我们将设备ID格式化为预期的QByteArray消息结构.将消息传递给线程以进行发送.(从QSerialPort BlockingMaster
示例修改的线程.
void Device::currentStatus(QList<Device *> * deviceList){
QString devID, updateQry;
int devStatus, updateStatus;
updateStatus=0;
QSqlQuery query;
for(int i=0; i<deviceList->size(); i++){
if(deviceList->at(i)->type == "Light"){
devStatus = deviceList->at(i)->status; …
Run Code Online (Sandbox Code Playgroud) 以下代码在Windows中正确地适用于我,但Linux不起作用.我使用相同的PC,两个操作系统都是原生安装的.我不使用虚拟机.我需要在Linux上工作.我已尝试过不同的Linux发行版,但无法在任何地方使用.
// In the main class:
QSerialPortInfo info = XXXX; // Generally in Linux: /dev/ttyUSB0, in win: COM1
QSerialPort serial;
QObject::connect(&serial, SIGNAL(readyRead()), this, SLOT(onReadyRead()), Qt::DirectConnection);
QObject::connect(&serial, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)), Qt::DirectConnection);
QObject::connect(&serial, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(onError(QSerialPort::SerialPortError)), Qt::DirectConnection);
// Slot
void MyClass::onReadyRead()
{
qDebug()<<"Signal onReadyRead";
buffer_mutex.lock();
buffer += serial.readAll();
qDebug()<<"Read: "<<qstr_to_hexstr(buffer);
bufferNotEmpty.wakeAll();
buffer_mutex.unlock();
}
void MyClass::onError(QSerialPort::SerialPortError error) {
qCritical()<<"Serial Port Error: "<<(int)error;
}
void MyClass::onBytesWritten(qint64 size){
qDebug()<<"onBytesWritten: "<<size;
}
// In another place I did:
serial.setPort(info);
if(!serial.open(QIODevice::ReadWrite))
return false;
qDebug()<<"Init Setting!...";
if(!serial.setBaudRate(QSerialPort::Baud9600))
qCritical()<<"Error …
Run Code Online (Sandbox Code Playgroud) 按照官方文档,我正在尝试这样做:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QThread *thread = new QThread;
Worker *worker= new Worker();
worker->moveToThread(thread);
//init connections
thread->start();
}
Run Code Online (Sandbox Code Playgroud)
工人构造函数:
Worker::Worker(QObject *parent) :
QObject(parent)
{
serial = new QSerialPort(this); //passing the parent, which should be the current thread
}
Run Code Online (Sandbox Code Playgroud)
没有编译错误但是当我执行它时会抛出这个:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0x11bd1148), parent's thread is QThread(0x11bd2ef8), current thread is QThread(0x3e47b8)
Run Code Online (Sandbox Code Playgroud)
也就是说,它告诉我serial
作为父线程的主线程而不是我创建的线程.
如果我不在构造函数中实例化序列但在主进程中实例化相同的结果,这是在我们调用之后触发的thread->start()
:
Worker::Worker(QObject *parent) :
QObject(parent)
{
}
Worker::doWork()
{
if(!serial) …
Run Code Online (Sandbox Code Playgroud) 有没有办法使用Qt发送信号或任何其他方式来判断USB串口线是否已拔下?
结果是静态链接正在工作,但仅适用于Qt库.我的第三方库QtSerialPort没有静态链接.经过一些研究,我发现我要么静态地构建这个库,要么我必须直接链接到.pro文件中的.pri文件.
我不知道怎么做,因为看起来QtSerialPort还没有设计用于静态链接.
.pri方法我真的不明白,并且在这两个链接中含糊不清地描述:http : //qt-project.org/forums/viewthread/15223 http://www.qtcentre.org/archive/index.php /t-54505.html
有没有人对如何让这些方法中的任何一种有效?或者可能另一种方法?
此外,MSVCP100.dll没有静态链接,如果有人可以给我任何建议.
================================================== ================================
我试图让Qt静态链接库,以便我可以创建一个独立的应用程序.我已经遵循了各种关于如何静态构建Qt然后构建静态应用程序的教程,但我没有太多运气.我相信我已经成功地使用静态链接构建Qt,因为应用程序的大小从79KB增加到7 + MB但我仍然收到错误,说QtCore4.dll和QtSerialPort.dll丢失了.另外,我在使用这个静态配置时遇到的另一个问题是,当我关闭我的程序时,Windows认为它已经崩溃,并给我一个窗口说MyProgram.exe已停止工作...
我在使用MSVC 2010和Qt 4.8.5的Windows机器上,并使用第三方库QtSerialPort.
根据我一直在阅读的指南,我所做的是:
下载并解压缩qt-everywhere-opensource-src-4.8.5.zip打开/mpecpec/mwin32-msvc2010/qmake.conf并将以下行更改为
CONFIG += qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files debug_and_release debug_and_release_target
Run Code Online (Sandbox Code Playgroud)
和
QMAKE_CLFAGS_RELEASE = -O2 -MT
Run Code Online (Sandbox Code Playgroud)
然后我打开MSVC2010命令提示符并cd到此.然后我输入命令
configure -static -release -platform win32-msvc2010
nmake sub-src
Run Code Online (Sandbox Code Playgroud)
完成此操作后,我打开我的项目并添加
CONFIG += static
Run Code Online (Sandbox Code Playgroud)
到.pro文件.在QtCreator中,然后我进入项目,管理工具包然后进入Qt版本并浏览到我刚刚生成的qMake.我在这个版本的qMake中添加了一个新工具包.然后我清理所有并切换到这个新工具包并从QtCreator运行qmake.然后我使用msvc2010命令提示符转到生成文件的目录然后
nmake release
Run Code Online (Sandbox Code Playgroud)
这会产生一个相当大的.exe,但就像我说的那样,它仍然取决于一对.dll的.
当Qt app使用QSerialPort
经历非干净关闭(例如由于接收和不处理SIGINT
)时,串口的文件描述符如何受到影响?
在运行打开QSerialPort
on 的应用程序/dev/ttyS0
,然后退出之后Ctl-C
,我发现它cat < /dev/ttyS0
立即返回(没有打印任何内容)而不是等待数据(通常如此).
我希望如果这是由于一个打开的文件句柄左转,它会显示在输出中lsof
,但lsof | grep ttyS0
什么都不返回.(我不确定如何在特定文件描述符上搜索句柄.)
我意识到这是一个XY问题,因为我可以通过重写我的应用程序来正确处理来完全避免这个问题SIGINT
,但我想更深入地了解这里发生了什么以及是否有办法恢复序列在它处于这种状态时的端口.
编辑:根据要求,这是输出strace cat /dev/ttyS0
:
execve("/bin/cat", ["cat", "/dev/ttyS0"], [/* 17 vars */]) = 0
brk(0) = 0x91ce000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76fb000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, …
Run Code Online (Sandbox Code Playgroud) 我使用本教程:http : //doc-snapshot.qt-project.org/qt5-stable/qtserialport/blockingmaster.html
但是当我想运行它时,Qt Creator 会产生以下错误:
错误:QT 中的未知模块:串行端口
当我按住鼠标时,#include <QtSerialPort/QSerialPort>
它说:
不包含这样的文件或目录
我使用 Qt 有5.0.1
什么想法吗?
qt ×10
qtserialport ×10
c++ ×8
linux ×2
qtcore ×2
qthread ×2
serial-port ×2
filehandle ×1
linux-kernel ×1
qbytearray ×1
qt-creator ×1
qt-signals ×1
qt4 ×1
qt5 ×1