QtControlCenter-master(智能快递柜上位机-传感器串口通信-场景页面交互-页面美化)

 

 

【】串口操作函数 使用线程 CSerialPort.cpp

CSerialPort.cpp

 

#pragma once

#pragma execution_character_set("utf-8")

#include <QObject>

#include <QSerialPort>

#include <QSerialPortInfo>

#include "define.h"

#include <QThread>

#include <QWaitCondition>

#include "include/HSingleton/HSingleton.h"

 

class CSerialPort_232 : public QObject, public QThread

{

    Q_OBJECT

public:

    CSerialPort_232(QObject *parent = nullptr);

 

    ~CSerialPort_232();

public:

    void InitSerial();            //��ʼ����������

    void close();

public:

    void AddTask(QString strSend);

 

    virtual void run();

 

    void StopThread();

 

    void setReadState(bool bRead);

 

signals:

    void sig_ReadData(QString strData);

 

public slots:

    void readData(); //��ȡ��������

 

private slots:

    void sendData(QString data); //���ʹ������ݴ�����

 

private:

 

    QextSerialPort * com; //����ͨ�Ŷ���

    QTimer *timer; //����������ʱ��

    bool comOk; //�����Ƿ�����

    QWaitCondition Thread_Wait;

private:

    QMutex m_QueyeMutex;

    QQueue<QString>     m_szSendQueue;                //ϴ�����

    volatile bool m_bAlive;

public:

    bool m_bRead;

};

 

 

#define gbl232SerialPort HSingletonTemplatePtr<CSerialPort_232>::get()

 

 

 

 

class CSerialPort_485 : public QObject, public QThread

{

    Q_OBJECT

 

public:

    CSerialPort_485(QObject *parent =nullptr);

 

    ~CSerialPort_485();

 

    void InitSerial();            //��ʼ����������

 

 

    void close();

 

public:

    void AddTask(QString strSend);

 

    virtual void run();

 

    void StopThread();

signals:

    void sig_ReadData(QString strData);

 

public slots:

    void readData(); //��ȡ��������

 

private slots:

    void sendData(QString data); //���ʹ������ݴ�����

private:

 

    QextSerialPort *com; //����ͨ�Ŷ���

    QTimer *timer; //����������ʱ��

    bool comOk; //�����Ƿ�����

    QWaitCondition Thread_Wait;

private:

    QMutex m_QueyeMutex;

    QQueue<QString>     m_szSendQueue;                //ϴ�����

    volatile bool m_bAlive;

 

};

 

 

#define gbl485SerialPort HSingletonTemplatePtr<CSerialPort_485>::get()

 

 

 

 

class CHeightPort_485 : public QObject, public QThread

{

    Q_OBJECT

 

public:

    CHeightPort_485(QObject *parent = nullptr);

 

    ~CHeightPort_485();

 

    void InitSerial();            //��ʼ����������

 

 

    void close();

 

public:

    void AddTask(QString strSend);

 

    virtual void run();

 

    void StopThread();

signals:

    void sig_ReadData(QString strData);

 

public slots:

    void readData(); //��ȡ��������

 

private slots:

    void sendData(QString data); //���ʹ������ݴ�����

private:

 

    QextSerialPort * com; //����ͨ�Ŷ���

    QTimer *timer; //����������ʱ��

    bool comOk; //�����Ƿ�����

    QWaitCondition Thread_Wait;

private:

    QMutex m_QueyeMutex;

    QQueue<QString>     m_szSendQueue;                //ϴ�����

    volatile bool m_bAlive;

 

};

 

 

#define gbl485HeightPort HSingletonTemplatePtr<CHeightPort_485>::get()

 

+使用队列存储需要发送的消息

    QMutex m_QueyeMutex;

    QQueue<QString>     m_szSendQueue;                //ϴ�����

    volatile bool m_bAlive;

+从队列中取出消息并且发送(在线程的run函数中实现)使用了数据锁机制

void CSerialPort_485::run()

{

    while (m_bAlive)

    {

        m_QueyeMutex.lock();

        int nSize = m_szSendQueue.size();

        if (nSize > 0)

        {

            QString strSend = m_szSendQueue.dequeue();

            m_QueyeMutex.unlock();

            this->msleep(50);

            sendData(strSend);        

            continue;

        }

        else

        {

            Thread_Wait.wait(&m_QueyeMutex);

            m_QueyeMutex.unlock();

        }

    }

}

【】串口 上层控制函数 控制开门 读取 传感器信息

void QPortControl::slot_ReadData(QString strRecevice)

{

    LOG_INFO("slot_ReadData =[%s]", strRecevice.toStdString().c_str());

 

 

 

 

    //上位机收到开门请求

    if (strRecevice.toUpper() == WantOpenDoor)

    {

        //上位机发送开始执行开门动作

        m_Action = Action_OpenDoor;

        gbl485SerialPort->AddTask(StartOpenDoor);

        return;

    }

    //上位机发送开始执行开门动作

    if (strRecevice.toUpper() == StartOpenDoor && m_Action == Action_OpenDoor)

    {        

        gbl485SerialPort->AddTask(AskOpenDoor);

        return;

    }

    //上位机发送开始执行开门动作

    if (strRecevice.toUpper() == OpenDoorFail && m_Action == Action_OpenDoor)

    {

        gbl485SerialPort->AddTask(AskOpenDoor);

        return;

    }

    //上位机收到开门成功的信号

    if (strRecevice.toUpper() == OpenDoorSucess&& m_Action == Action_OpenDoor)

    {

        m_Action = Action_Null;

        emit sig_OpendoorFinish();    

        return;

    }

 

    /**********关门*****************/

    //上位机收到关门请求

    if (strRecevice.toUpper() == WantDoorClose)

    {

        //上位机发送开始执行关门动作

        m_Action = Action_CloseDoor;

        gbl485SerialPort->AddTask(StartCloseDoor);

        return;

    }

    //上位机询问是否完成关门门动作?

    if (strRecevice.toUpper() == StartCloseDoor && m_Action == Action_CloseDoor)

    {

        gbl485SerialPort->AddTask(AskCloseDoor);

        return;

    }

    //上位机发送开始执行关门动作

    if (strRecevice.toUpper() == CloseDoorFail && m_Action == Action_CloseDoor)

    {

        gbl485SerialPort->AddTask(AskCloseDoor);

        return;

    }

    //上位机收到关门成功的信号

    if (strRecevice.toUpper() == CloseDoorSucess && m_Action == Action_CloseDoor)

    {

        m_Action = Action_Null;

        emit sig_ClosedoorFinish();    

        return;

    }

 

    /**********吸住托盘*****************/

    //上位机收到吸住托盘请求

    if (strRecevice.toUpper() == WantSuckTray)

    {

        m_Action = Action_SuckTray;

        //上位机发送执行电磁体吸住托盘开始命令

        gbl485SerialPort->AddTask(StartSuckTray);

        return;

    }    

    if (strRecevice.toUpper() == StartSuckTray && m_Action == Action_SuckTray)

    {

        //上位机读取电磁吸盘动作是否执行完成?

        gbl485SerialPort->AddTask(AskSuckTray);

        m_nError = 0;

        return;

    }

    //上位机读取电磁吸盘动作是否执行完成

    if (strRecevice.toUpper() == SuckTrayFail && m_Action == Action_SuckTray)

    {

        if (m_nError == ERRORNUM)

        {

            m_Action = Action_Null;

            emit sig_SuckTrayFinish();

            m_nError = 0;

            return;

        }

        gbl485SerialPort->AddTask(AskSuckTray);    

        m_nError = m_nError + 1;

        return;

    }

    //完成吸住托盘

    if (strRecevice.toUpper() == SuckTraySucess && m_Action == Action_SuckTray)

    {

        m_Action = Action_Null;

        emit sig_SuckTrayFinish();

        return;

    }

 

    /*********放开托盘*****************/

    //上位机收到放开托盘请求

    if (strRecevice.toUpper() == WantDropTray)

    {

        //上位机发送执行电磁体放开托盘开始命令

        m_Action = Action_DropTray;

        gbl485SerialPort->AddTask(StartDropTray);

        return;

    }

    if (strRecevice.toUpper() == StartDropTray && m_Action == Action_DropTray)

    {

        //上位机读取电磁放盘动作是否执行完成?

        gbl485SerialPort->AddTask(AskDropTray );

        m_nError = 0;

        return;

    }

    //上位机读取电磁放开盘动作是否执行完成

    if (strRecevice.toUpper() == DropTrayFail && m_Action == Action_DropTray)

    {

        if (m_nError == ERRORNUM)

        {

            m_Action = Action_Null;

            emit sig_DropTrayFinish();

            m_nError = 0;

            return;

 

        }

        gbl485SerialPort->AddTask(AskDropTray);

        m_nError = m_nError + 1;

        return;

    }

    //完成放下托盘

    if (strRecevice.toUpper() == DropTraySucess && m_Action == Action_DropTray)

    {

        m_Action = Action_Null;

        emit sig_DropTrayFinish();

        return;

    }

 

    /**********拉取货物*****************/

    //PLC接收到上位机开门命令

    if (strRecevice.toUpper() == WantGetGoods)

    {

        //上位机发送开始执行拉取货物命令

        m_Action = Action_GetGoods;

        gbl485SerialPort->AddTask(StartGetGoods);

        return;

    }

    if (strRecevice.toUpper() == StartGetGoods && m_Action == Action_GetGoods)

    {

        //上位机读取电磁吸盘动作是否执行完成?

        gbl485SerialPort->AddTask(AskGetGoods);

        Sleep(10);

        GetHeight();

        return;

    }

    //上位机读取电磁吸盘动作是否执行完成

    if (strRecevice.toUpper() == GetGoodsFail && m_Action == Action_GetGoods)

    {

        gbl485SerialPort->AddTask(AskGetGoods);

        Sleep(10);

        GetHeight();

        return;

    }

    //完成拉取货物命令

    if (strRecevice.toUpper() == GetGoodsSucess && m_Action == Action_GetGoods)

    {

        m_Action = Action_Null;

        emit sig_GetGoodsFinish();

        return;

    }

 

    /**********推送到位*****************/

    //PLC接收到上位机推送货物命令

    if (strRecevice.toUpper() == WantPushGoods)

    {

        //收到并执行推送货物

        m_Action = Action_PushGoods;

        gbl485SerialPort->AddTask(StartPushGoods);

        return;

    }

    if (strRecevice.toUpper() == StartPushGoods && m_Action == Action_PushGoods)

    {

        //推送到位没有??

        gbl485SerialPort->AddTask(AskPushGoods);

        return;

    }

    //推送到位没有?

    if (strRecevice.toUpper() == PushGoodsFail && m_Action == Action_PushGoods)

    {

        gbl485SerialPort->AddTask(AskPushGoods);

        return;

    }

    //已经推送到位

    if (strRecevice.toUpper() == PushGoodsSucess && m_Action == Action_PushGoods)

    {

        m_Action = Action_Null;

        emit sig_PushGoodsFinish();

        return;

    }

 

    /********运动到行列******************/

    //PLC收到行数信息

    if (strRecevice.toUpper() == m_strMoveToX)

    {

        //发送列数信息

        m_Action = Action_Move;

        gbl485SerialPort->AddTask(m_strMoveToY);

        return;

    }

    //PLC收到列数信息

    if (strRecevice.toUpper() == m_strMoveToY && m_Action == Action_Move)

    {

        //开始运动到相应的行、列

        gbl485SerialPort->AddTask(StartMove);

        return;

    }

    //PLC收到列数信息

    if (strRecevice.toUpper() == StartMove && m_Action == Action_Move)

    {

        //开始运动到相应的行、列

        gbl485SerialPort->AddTask(AskMove);

        return;

    }

 

    //上位机询问是否达到相应的行、列位置?

    if (strRecevice.toUpper() == MoveFail && m_Action == Action_Move)

    {

        gbl485SerialPort->AddTask(AskMove);

        return;

    }

    //已达到指定行、列位置

    if (strRecevice.toUpper() == MoveSucess && m_Action == Action_Move)

    {

        m_Action = Action_Null;

        emit sig_MoveFinish();

        return;

    }

 

    if (strRecevice.indexOf("3A 30 32 30 33 30 32") != -1)

    {

        emit sig_ReadSetting(m_Action, strRecevice);

        return;

    }

}

 

【】模板形式实现 类的单例 实现只有一个CRunTime配置类

 

 

*【】串口配置界面

 

*标题

 

*【】配置文件设置 使用Qsettings文件读写 设置参数 读取 串口和网络 网络自动重连

/* $Copyright (c) 2006-2016 Green Net World

*

* Author    :    Maga version 1.0

* DateTime    :    2016-7-8 9:39:22

*

* http://www.gwchina.cn/

*

* CRunTime 运行时缓存数据

*/

 

 

 

 

#ifndef CRunTime_H

#define CRunTime_H

#include "../include/HSingleton/HSingleton.h"

 

#if _MSC_VER >= 1600

#pragma execution_character_set("utf-8")

#endif

 

 

enum WIDGET_TYPE

{

    MSGBOX_GET = 0x0001,

    MSGBOX_SAVE = 0x0002,

    MSGBOX_CLOSE = 0x0004,

    MSGBOX_BACK = 0x0008,

    MSGBOX_HOME = 0x00010,

    MSGBOX_OK = 0x00020,

    MSGBOX_RETURN = 0x00040

};

 

class QString;

/** 单例模式类 CRunTime */

class CRunTime

{

public:

 

    /** 默认构造函数(使用私有,不允许外部直接构造) */

    CRunTime();

 

public:

 

    /** 默认析构函数 */

    ~CRunTime();

 

    // 清空

    void        Clear();

public:

QString PortName; //串口号

int BaudRate; //波特率

int DataBit; //数据位

QString Parity;                 //校验位

double StopBit; //停止位

 

bool HexSend; //16进制发送

bool HexReceive; //16进制接收

 

    QString com232_PortName; //串口号

    int com232_BaudRate; //波特率

    int com232_DataBit; //数据位

    QString com232_Parity;                 //校验位

    double com232_StopBit; //停止位

    bool com232_HexSend; //16进制发送

    bool com232_HexReceive; //16进制接收

 

    QString com485_PortName; //串口号

    int com485_BaudRate; //波特率

    int com485_DataBit; //数据位

    QString com485_Parity;                 //校验位

    double com485_StopBit; //停止位

    bool com485_HexSend; //16进制发送

    bool com485_HexReceive; //16进制接收

 

 

bool Debug; //模拟设备

bool AutoClear; //自动清空

 

bool AutoSend; //自动发送

int SendInterval; //自动发送间隔

bool AutoSave; //自动保存

int SaveInterval; //自动保存间隔

 

QString SendFileName; //发送配置文件名

QString DeviceFileName; //模拟设备数据文件名

 

QString Mode; //转换模式

QString ServerIP; //服务器IP

    QString strComputerUrl; //公司的网址

int ServerPort; //服务器端口

int ListenPort; //监听端口

int SleepTime; //延时时间

bool AutoConnect; //自动重连

 

void ReadConfig(); //读取配置文件,在main函数最开始加载程序载入

void WriteConfig(); //写入配置文件,在更改配置文件程序关闭时调用

void NewConfig(); //以初始值新建配置文件

bool CheckConfig(); //校验配置文件

void WriteError(QString str);//写入错误信息

void NewDir(QString dirName);//新建目录

 

 

    QString Recevice_485;

    QString Recevice_232;

    QString Recevice_Height;

    QString strWeight;

    QString strHeight;

    int InputNum;

    WIDGET_TYPE m_type;

 

};

 

 

#define gblRuntimeData HSingletonTemplatePtr<CRunTime>::get()

 

#endif // CRunTime_H

 

*标题

 

*标题

 

 

【】*取件码键盘

 

+设置无边框

this->setupUi(this);

    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint );

    this->setWindowIcon(QIcon(":/Image/Resources/Image/zhihuiwu.ico"));

    display->setFocus();

+正则表达式

 

    QRegExp regx("[0-9]+$");

    QValidator *validator = new QRegExpValidator(regx, display);

    display->setValidator(validator);

    display->hide();

 

+按键设置样式表

 

void NumKeyBoard::button_init()

{

    //数字色值:#7a7675。 字号64px

 

    display->setStyleSheet("QLineEdit{font-size:25px;color:rgb(0,0,0);"

        "height:50px;border:2px solid rgb(4,167,240);"

        "border-radius:10px;}");

    toolButton_0->setStyleSheet("QToolButton{border:2px groove white;border-radius:10px;"

        "background-color:rgb(4,167,240);color:white;font-size:25px}");

    toolButton_1->setStyleSheet("QToolButton{border:2px groove white;border-radius:10px;"

        "background-color:rgb(4,167,240);color:white;font-size:25px}");

    toolButton_2->setStyleSheet("QToolButton{border:2px groove white;border-radius:10px;"

        "background-color:rgb(4,167,240);color:white;font-size:25px}");

    toolButton_3->setStyleSheet("QToolButton{border:2px groove white;border-radius:10px;"

        "background-color:rgb(4,167,240);color:white;font-size:25px}");

    toolButton_4->setStyleSheet("border:2px groove gray;border-radius:10px;"

        " background-color:rgb(4,167,240);color:white;font-size:25px");

    toolButton_5->setStyleSheet("QToolButton{border:2px groove white;border-radius:10px;"

        "background-color:rgb(4,167,240);color:white;font-size:25px}");

    toolButton_6->setStyleSheet("QToolButton{border:2px groove white;border-radius:10px;"

        "background-color:rgb(4,167,240);color:white;font-size:25px}");

    toolButton_7->setStyleSheet("QToolButton{border:2px groove white;border-radius:10px;"

        "background-color:rgb(4,167,240);color:white;font-size:25px}");

    toolButton_8->setStyleSheet("border:2px groove gray;border-radius:10px;"

        " background-color:rgb(4,167,240);color:white;font-size:25px");

    toolButton_9->setStyleSheet("QToolButton{border:2px groove white;border-radius:10px;"

        "background-color:rgb(4,167,240);color:white;font-size:25px}");

    toolButton_backspace->setStyleSheet("border:2px groove gray;border-radius:10px;"

        " background-color:rgb(4,167,240);color:white;font-size:25px");

    toolButton_enter->setStyleSheet("QToolButton{border:2px groove white;border-radius:10px;"

        "background-color:rgb(4,167,240);color:white;font-size:25px}");

 

 

}

+设置存件 和 取件 样式不一样

 

void NumKeyBoard::Init(WIDGET_TYPE types)

{

    m_type = types;

    if (types & MSGBOX_GET)

    {

        label_title->setStyleSheet("min-379px;"

                                 "max-379px;"

         "min-height:71px;"

                                 "max-height:71px;"

                                 "border-image: url(:/Image/Resources/Image/请输入取件码.png);");

    }

    if (types & MSGBOX_SAVE)

    {

        label_title->setStyleSheet("min-379px;"

                                 "max-379px;"

                                 "min-height:71px;"

             "max-height:71px;"

             "border-image: url(:/Image/Resources/Image/请输入存件码.png);");

    }

}

 

+输入字符串有误 判断

 

    waitingForOperand = true;

    text = display->text();

    int i = text.indexOf("-");

    if (text.length()!=6 || i!=-1)

    {

        QMessageBox::about(nullptr, "onEnter", "输入的字符有误");

        return;

    }

 

*【】自定义键盘(QSignalMapper所有按键,获取键值)

+设置大小写

 

void KeyBoard::onCapslock()

{

caps_Lock = !caps_Lock;

if(caps_Lock)

{

//letter

ui->toolButton_a->setText("A");

ui->toolButton_b->setText("B");

ui->toolButton_c->setText("C");

ui->toolButton_d->setText("D");

ui->toolButton_e->setText("E");

ui->toolButton_f->setText("F");

ui->toolButton_g->setText("G");

ui->toolButton_h->setText("H");

ui->toolButton_i->setText("I");

ui->toolButton_j->setText("J");

ui->toolButton_k->setText("K");

ui->toolButton_l->setText("L");

ui->toolButton_m->setText("M");

ui->toolButton_n->setText("N");

ui->toolButton_o->setText("O");

ui->toolButton_p->setText("P");

ui->toolButton_q->setText("Q");

ui->toolButton_r->setText("R");

ui->toolButton_s->setText("S");

ui->toolButton_t->setText("T");

ui->toolButton_u->setText("U");

ui->toolButton_v->setText("V");

ui->toolButton_w->setText("W");

ui->toolButton_x->setText("X");

ui->toolButton_y->setText("Y");

ui->toolButton_z->setText("Z");

// toolButton_line1->setText("<");

// toolButton_line2->setText(">");

// toolButton_line3->setText("-");

// toolButton_dot->setText("*");

// toolButton_wenhao->setText("#");

}

+键盘输入框设置为密码模式 正常模式

 

void KeyBoard::onInvMode()

{

if(inputMode == iMode_Normal)

{

inputMode = iMode_Passwd;

}

else if(inputMode == iMode_Passwd)

{

inputMode = iMode_Normal;

}

 

if(inputMode == iMode_Normal)

{

ui->display->setEchoMode(QLineEdit::Normal);

}

else if(inputMode == iMode_Passwd)

{

ui->display->setEchoMode(QLineEdit::Password);

}

}

+按键回退backspace

 

void KeyBoard::onBackspace()

{

ui->display->backspace();

}

+鼠标拖拽

 

/*支持鼠标拖拽键盘*/

void KeyBoard::mouseMoveEvent(QMouseEvent *event)

{

if (event->buttons() == Qt::LeftButton)

{

move(event->globalPos() - dragPosition);

event->accept();

}

}

 

void KeyBoard::mousePressEvent(QMouseEvent *event)

{

if (event->button() == Qt::LeftButton)

{

dragPosition = event->globalPos() - frameGeometry().topLeft();

event->accept();

}

if (event->button() == Qt::RightButton)

{

close();

}

}

+光标右移 左移

void KeyBoard::onCursorRight()

{

ui->display->cursorForward(false,1);

}

void KeyBoard::onCursorRight()

{

ui->display->cursorForward(false,1);

}

【】*全局设置 使用静态成员函数 可以通过类名加域作用运算符访问,

+延时

//延时

static void sleep(int sec)

{

QTime dieTime = QTime::currentTime().addMSecs(sec);

 

while (QTime::currentTime() < dieTime) {

QCoreApplication::processEvents(QEventLoop::AllEvents, 100);

}

}

 

+窗体居中显示

 

+设置系统日期时间

 

+十六进制与字符 十进制 互化

 

+生成二维码

//生成二维码

    static QPixmap MakeQRPixmap(const QString& strQRCode, const QPixmap& midPix, int size)

    {

        CQR_Encode m_encode;

        m_encode.EncodeData(QR_LEVEL_M, 0, true, -1, strQRCode.toStdString().c_str());

        int imageSize = m_encode.m_nSymbleSize + (QR_MARGIN * 2);

        QImage temp(QSize(imageSize, imageSize), QImage::Format_RGB32);

        temp.fill(QColor(255, 255, 255));

        for (int i = 0; i < m_encode.m_nSymbleSize; i++)

        {

            for (int j = 0; j < m_encode.m_nSymbleSize; j++)

            {

                if (m_encode.m_byModuleData[i][j])

                {

                    temp.setPixel(i + QR_MARGIN, j + QR_MARGIN, RGB(0, 0, 0));

                }

            }

        }

        QPixmap pix = QPixmap::fromImage(temp);

        pix = pix.scaled(QSize(size, size), Qt::KeepAspectRatio);

        QPainter painter(&pix);

        if (!midPix.isNull())

        {

            painter.drawPixmap((pix.width() - midPix.width()) / 2, (pix.height() - midPix.height()) / 2, midPix);

            painter.end();

        }

        return pix;

    }

 

*延时

 

*延时

 

*延时

 

*延时

 

*延时

 

*延时

 

*延时

 

*延时

 

*延时

 

原文地址:https://www.cnblogs.com/tangyuanjie/p/14304630.html