• 7130阅读
  • 5回复

[提问]QserialPort与QThread使用 [复制链接]

上一主题 下一主题
离线harold00124
 

只看楼主 倒序阅读 楼主  发表于: 2016-11-04

不好意思又来请教各位大大了
这次老板出的作业是要我做
要和RS232做全雙工的資料傳送接收
port插入後會有Tx跟Rx兩個 port 在電腦新增com5.com6(老板有给我USB的RS458模拟盒当做测试器)

目前我查資料之後按照我自己的想法可能會需要用到
QThread創造兩個線程確保全雙工進行傳送接收
用QMutex確保傳送接收資料不阻塞
QserialPort抓取port放到combobox內
用readall()接收 用write傳送
按一個pushbutton後開啟全雙工傳送接收 输入与显示初步設定顯示在lineEdit 1、2
線路中斷的時候自動出現提示messagebox提示錯誤並且終止程式線程

请问 如何使用QserialPort主动抓取所有可用的port并且放入combobox的addItem内
QThread要如何配合使用?

我自己有练习2个单功能的程式
文件 mythread

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include<QThread>

class mythread : public QThread
{
public:
    mythread();//新增線程類
    void run();//線程函數
    QString name;
};

#endif // MYTHREAD_H
-----------------------------------------------------------------
主文件main


#include <QCoreApplication>
#include"mythread.h" //帶入線程標頭

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    mythread mthread1;//線程子類1
    mthread1.name="mthread1";

    mythread mthread2;//線程子類2
    mthread2.name="mthread2";

    mythread mthread3;//線程子類3
    mthread3.name="mthread3";

    mthread1.start(QThread::HighestPriority);//執行1 優先權設定為高
    mthread2.start();//執行2
    mthread3.start(QThread::HighestPriority);//執行3 優先權設定為高

    return a.exec();
}
----------------------------------------------------------------------------------

#include "mythread.h"
#include <QDebug>
mythread::mythread()
{

}

void mythread::run()
{
    qDebug()<<this->name<<"Running";

    for(int i=0;i<10000;i++){
        qDebug()<<this->name<<i;
    }
}
----------------------------------------------------------------------------------
还有QserialPort的练习
头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void serialReceived();

    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
--------------------------------------------------------------
主文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include<QtSerialPort/QSerialPort>
#include<QDebug>
QSerialPort *serial;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    serial=new QSerialPort(this);
    serial->setPortName("com6");
    serial->setBaudRate(QSerialPort::Baud9600);
    serial->setDataBits(QSerialPort::Data8);
    serial->setParity(QSerialPort::NoParity);
    serial->setStopBits(QSerialPort::OneStop);
    serial->setFlowControl(QSerialPort::NoFlowControl);
    serial->open(QIODevice::ReadWrite);
    serial->write("OK*");
    connect(serial,SIGNAL(readyRead()),this,SLOT(serialReceived()));
}


MainWindow::~MainWindow()
{
    delete ui;
    serial->close();
}

void MainWindow::serialReceived(){
    QByteArray ba;
    ba=serial->readAll();
    ui->label->setText(ba);
    qDebug()<<ba;
}

void MainWindow::on_pushButton_clicked()
{
    serial->write(ui->lineEdit->text().toStdString().data());
}
--------------------------------------------------------------------
单个做我按照网路上的教学影片都有做出来也能正常执行

不过叫我两个弄在一起做再加上其他功能我又迷胡了....

然后QT的范例又是各种看不懂.............

我在ui界面上是这样做的... 数字部份应该没啥问题我应该能解决就不提问了...
window.open('http://www.qtcn.org/bbs/attachment/Mon_1611/17_176460_6101a3c74713af5.jpg?350');" style="max-width:700px;max-height:700px;" onload="if(is_ie6&&this.offsetWidth>700)this.width=700;" >



跪求大大指点迷津

离线harold00124

只看该作者 1楼 发表于: 2016-11-04
我已经找到抓取port的方式了
#include<QSerialPortInfo>


    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            ui->comboBox->addItem(info.portName());
        }
请问一下    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())这句到底是在说蛇么啊? 如何运作的??


還有



void MainWindow::on_pushButton_2_clicked()
{
    serial->setPortName(ui->comboBox->currentText());//窗口號
    serial->setBaudRate(QSerialPort::Baud9600);//傳輸率
    serial->setDataBits(QSerialPort::Data8);//數據位
    serial->setParity(QSerialPort::NoParity);//較驗位
    serial->setStopBits(QSerialPort::OneStop);//停止位
    serial->setFlowControl(QSerialPort::NoFlowControl);//設置流控制
    serial->open(QIODevice::ReadWrite);//功能設定 讀寫
    serial->write("OK*");//預設傳輸資料
    serial->write(ui->lineEdit_2->text().toStdString().data());
}

我開程式後選com5 按鍵執行後com5的燈會亮
但是我選com6就還是亮com5的燈
反之亦然 請問這是怎麼回事 我哪裡做錯了嗎?

怎麼選只能選一次 後面再改comport都沒用了

离线bran_lee

只看该作者 2楼 发表于: 2016-11-04
回 harold00124 的帖子
harold00124:我已经找到抓取port的方式了
#include<QSerialPortInfo>
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
....... (2016-11-04 13:07)

你改端口参数前都不需要close吗?
1条评分金钱+10
harold00124 金钱 +10 感謝指點迷津!! 大大一點就點破我的問題了 2016-11-04
当你只有锤子时,你看什么都像是钉子!
离线harold00124

只看该作者 3楼 发表于: 2016-11-04
回 bran_lee 的帖子
bran_lee:你改端口参数前都不需要close吗?
(2016-11-04 15:59)

喔 我懂了 謝謝大大 我從你說的close去找資料終於發現自己的問題了@@....


serial->close();
    serial->setPortName(ui->comboBox->currentText());//窗口號
    serial->open(QIODevice::ReadWrite);//功能設定 讀寫
    serial->setBaudRate(QSerialPort::Baud9600);//傳輸率
    serial->setDataBits(QSerialPort::Data8);//數據位
    serial->setParity(QSerialPort::NoParity);//較驗位
    serial->setStopBits(QSerialPort::OneStop);//停止位
    serial->setFlowControl(QSerialPort::NoFlowControl);//設置流控制
    serial->write("OK*");//預設傳輸資料
    serial->write(ui->lineEdit_2->text().toStdString().data());

Open跟close拉一下就搞定了 真是..
离线harold00124

只看该作者 4楼 发表于: 2016-11-07
再次感谢大大的提点

portfors232.rar (6 K) 下载次数:0

后来我问了一下我的老板 要做全双工到底传输量有多大?

老板回答我说1K以下  跟我原本预想500K以上相差巨大

由于传输量不大所以我没有用多线程的方式..话说多线程的QserialPort我到现在还是看不懂

使用设定
选择好RT 与TX后按下Set Port会将combbox选取的值设定到TXRX的设定值内并且清空所有textEdit的内容
设定好TXRX后 在lineEdit内输入想要传送的资料 会把资料传送到TX Port 并且在传送textEdit

还请大神多多关照 如可以的话可以稍为指点小弟多线程QserialPort就更千恩万谢了


以下代码区
文件



#include <QtSerialPort/QSerialPort>
#include <QSerialPortInfo>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);


    ~MainWindow();

private slots:
    void portreaddate();

    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_comboBox_activated(const QString &arg1);

    void Setcom(int iBautRate, int iDataBits,QString chParity,QString chStopBits);

    void on_comboBox_6_activated(const QString &arg1);

private:
    Ui::MainWindow *ui;
    QComboBox *BuatRate;
    QComboBox *DataBits;
    QComboBox *Party;
    QComboBox *StopBit;
};

#endif // MAINWINDOW_H



#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
QSerialPort *serial;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            ui->comboBox->addItem(info.portName());//添加串口
            ui->comboBox_6->addItem(info.portName());
        }
    serial=new QSerialPort(this);


    BuatRate=ui->comboBox_2;
    DataBits=ui->comboBox_3;
    Party=ui->comboBox_4;
    StopBit=ui->comboBox_5;

    connect(serial,SIGNAL(readyRead()),this,SLOT(portreaddate()));

}

MainWindow::~MainWindow()
{
    delete ui;
    serial->close();
}
void MainWindow::portreaddate(){
    QByteArray Rx;
    Rx=serial->readAll();
    ui->textEdit->setText(ui->textEdit->toPlainText()+Rx);
}

void MainWindow::on_pushButton_clicked()
{
    Setcom(BuatRate->currentIndex(),
           DataBits->currentIndex(),
           Party->currentText(),
           StopBit->currentText());
}


void MainWindow::on_pushButton_2_clicked()
{\

    serial->write(ui->lineEdit->text().toStdString().data());
    ui->textEdit_2->setText(ui->textEdit_2->toPlainText()+ui->lineEdit->text().toStdString().data());
}

void MainWindow::Setcom(int iBautRate,int iDataBits,QString chParity,QString chStopBits)
{
    serial->clear();
    ui->textEdit->clear();
    ui->textEdit_2->clear();
    serial->close();
    serial->setPortName(ui->comboBox->currentText());
    serial->open(QIODevice::ReadWrite);


    switch (iBautRate) {
    case 2400:
        serial->setBaudRate(QSerialPort::Baud2400);
        break;
    case 4800:
        serial->setBaudRate(QSerialPort::Baud4800);
        break;
    case 9600:
        serial->setBaudRate(QSerialPort::Baud9600);
        break;
    case 19200:
        serial->setBaudRate(QSerialPort::Baud19200);;
        break;
    case 38400:
        serial->setBaudRate(QSerialPort::Baud38400);
        break;
    case 57600:
        serial->setBaudRate(QSerialPort::Baud57600);
        break;
    case 115200:
        serial->setBaudRate(QSerialPort::Baud115200);
        break;
    }


    switch (iDataBits) {
    case 8:
        serial->setDataBits(QSerialPort::Data8);
        break;
    case 7:
        serial->setDataBits(QSerialPort::Data7);
        break;
    case 6:
        serial->setDataBits(QSerialPort::Data6);
        break;
    case 5:
        serial->setDataBits(QSerialPort::Data5);
        break;}

    if(chParity=="None") {
        serial->setParity(QSerialPort::NoParity);
     }
    else if(chParity=="Odd"){
        serial->setParity(QSerialPort::OddParity);
     }
    else if(chParity=="Even"){
        serial->setParity(QSerialPort::EvenParity);
     }
    else if(chParity=="Mark"){
        serial->setParity(QSerialPort::MarkParity);
     }
    else if(chParity=="Space"){
        serial->setParity(QSerialPort::SpaceParity);
     }


    if(chStopBits=="OnStop"){
        serial->setStopBits(QSerialPort::OneStop);
     }
    else if (chStopBits=="OneAndHalfStop"){
        serial->setStopBits(QSerialPort::OneAndHalfStop);
     }
    else if(chStopBits=="TwoStop") {
        serial->setStopBits(QSerialPort::TwoStop);
     }

}

void MainWindow::on_comboBox_6_activated(const QString &arg1)
{

}

void MainWindow::on_comboBox_activated(const QString &arg1)
{

}


实际执行状况

离线bran_lee

只看该作者 5楼 发表于: 2016-11-08
回 harold00124 的帖子
harold00124:再次感谢大大的提点
[图片]portfors232.rar (6 K) 下载次数:0
后来我问了一下我的老板 要做全双工到底传输量有多大?
....... (2016-11-07 16:41) 

我觉得你首先需要了解QThread的用法,run和moveToThread,还有信号的几种连接方式的区别。然后要在线程里用QSerialPort,要注意new、读、写操作都应该在同一个线程内完成,如果你以后用到多线程的socket,这是同样要注意的问题。除非传输量真的很大,读写非常频繁,否则不要轻易用,比较麻烦。
1条评分金钱+10
harold00124 金钱 +10 感谢 我在多学习一下 2016-11-08
当你只有锤子时,你看什么都像是钉子!
快速回复
限100 字节
 
上一个 下一个