Windows 7 上的奇怪行为 QT QSerialPort 不会更改串行 com 端口的设置
Posted
技术标签:
【中文标题】Windows 7 上的奇怪行为 QT QSerialPort 不会更改串行 com 端口的设置【英文标题】:Weird behavior QT QSerialPort on windows 7 doesn't change the settings of the serial com port 【发布时间】:2016-07-19 18:15:19 【问题描述】:我正在编写一个 qt 桥以通过 Web 应用程序访问串行热敏打印机。 我在设置串口设置时遇到问题,这是我的代码:
bool Bridge::printToSerial(QByteArray arr, QString serialPortName, quint16 baud)
/*
QProcess proc;
QStringList args = QStringList() << QString("mode COM1 BAUD=%1 PARITY=%2 DATA=%3" ).arg(9600).arg( "n" ).arg(8);
proc.start( "cmd.exe", args );
proc.waitForStarted();
proc.close();
*/
QSerialPort* m_port = new QSerialPort(this);
m_port->setPortName(serialPortName); // \\.\COM1
if(!m_port->open(QSerialPort::ReadWrite))
qDebug() << "Error serial open";
else
if (arr.isEmpty())
qDebug() << QObject::tr("Either no data was currently available on the standard input for reading, or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
delete m_port;
return 1;
m_port->setBaudRate(baud);
m_port->setDataBits(QSerialPort::Data8);
m_port->setParity(QSerialPort::NoParity);
m_port->setStopBits(QSerialPort::OneStop);
//m_port->setBreakEnabled(true);
qint64 bytesWritten = m_port->write(arr);
if (bytesWritten == -1)
qDebug() << QObject::tr("Failed to write the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
delete m_port;
return 1;
else if (bytesWritten != arr.size())
qDebug() << QObject::tr("Failed to write all the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
delete m_port;
return 1;
else if (!m_port->waitForBytesWritten(500))
qDebug() << QObject::tr("Operation timed out or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
delete m_port;
return 1;
m_port->close();
delete m_port;
qDebug() << QObject::tr("Data successfully sent to port %1").arg(serialPortName) << endl;
return false;
delete m_port;
return true;
问题是数据打印但没有完成,这让我觉得数据位没有设置为 8 位。
我执行了命令:mode COM1,它显示端口配置不正确(波特率、位、奇偶校验全部错误)。顺便说一句,设备管理器显示端口的默认设置和与 cmd 行不同的结果:“mode COM1”
为了让它工作,我要么必须执行 cmd 行: 模式 COM1 BAUD=9600 PARITY=n DATA=8 在我运行程序之前。 或调用 m_port->setBreakEnabled(true);在我打开端口之后。此调用挂起程序,我必须重新编译 exe 而无法工作。 系统重启时,命令行模式显示旧结果(波特率 1200,数据位 7 等)
任何线索为什么我有这种行为? QSerialPort 似乎无法有效地更改我需要的所有设置。
【问题讨论】:
【参考方案1】:为什么每次发送一些数据时都要打开和关闭端口?此外,仅仅因为write
或waitForBytesWritten
已返回表明数据已“写入”的内容,这仅意味着数据已从***设备驱动程序的缓冲区中刷新。将所有数据实际推送到硬件的 USB 请求可能仍在等待处理,设备的 FIFO 可能仍有数据,等等。
然而,当您关闭设备时,您通常会中止任何仍在进行中的事务,并导致硬件清除其缓冲区。写入是异步和流式传输以保持性能,设备关闭是一种同步的即时结果类型的操作。
让您的设备保持打开状态。仅当您以特定于平台的方式获悉设备即将停用或添加新设备时,您才需要重新打开它。
【讨论】:
所以基本上,我必须跟踪我打开的端口,如果打开,则写入数据,否则:打开,写入数据并将端口标记为打开。有没有办法判断端口是否打开? @othmoz 这取决于你。保留您正在使用的端口列表。你不使用的显然不是你打开的,你正在使用的那些是保持打开的。就是这样。【参考方案2】:@Kuba Ober 是对的。我最终将函数修改为如下所示,跟踪打开的端口: (我不知道我是否应该为每个端口设置一个 QSerialPort 指针,或者像下面这样在我每次写入数据时使用它来重新定义端口设置,不过上面的工作。)
bool Bridge::printToSerial(QByteArray arr, QString serialPortName, quint16 baud)
if (arr.isEmpty())
qDebug() << QObject::tr("Either no data was currently available on the standard input for reading, or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
return false;
bool portOpen = m_opened.contains(serialPortName);
if(!portOpen)
if(m_port == NULL)
m_port = new QSerialPort(this);
m_port->setPortName(serialPortName);
if(!m_port->open(QSerialPort::WriteOnly))
qDebug() << "Error serial open";
return false;
portOpen = true;
m_opened[serialPortName] = true;
else
m_port->setPortName(serialPortName); // \\.\COM1
m_port->setBaudRate(baud);
m_port->setDataBits(QSerialPort::Data8);
m_port->setParity(QSerialPort::NoParity);
m_port->setStopBits(QSerialPort::OneStop);
qint64 bytesWritten = m_port->write(arr);
if (bytesWritten == -1)
qDebug() << QObject::tr("Failed to write the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
delete m_port;
return 1;
else if (bytesWritten != arr.size())
qDebug() << QObject::tr("Failed to write all the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
delete m_port;
return 1;
else if (!m_port->waitForBytesWritten(5000))
qDebug() << QObject::tr("Operation timed out or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
delete m_port;
return 1;
qDebug() << QObject::tr("Data successfully sent to port %1").arg(serialPortName) << endl;
return true;
【讨论】:
以上是关于Windows 7 上的奇怪行为 QT QSerialPort 不会更改串行 com 端口的设置的主要内容,如果未能解决你的问题,请参考以下文章
QT 5.1.1:QWebview 中的复选框在 Win 7 (x64) / Win 8 下显示奇怪的行为