这其中存在两个最基本的问题:
1.一个信号对应多个槽时,槽函数的执行顺序是怎样的???
2.多个信号对应一个槽时,如何在槽函数中判断信号的发出者是谁(来自哪个类的对象)?
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <tcpclient.h>
#include <spcomm.h>
#include <QJsonDocument>
#include <QJsonObject>
#include <QSettings>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
signals:
void connectToTcp(QString&, int&);
void disConnectToTcp();
protected:
void closeEvent(QCloseEvent *event);
public slots:
void connectOk();
void disConnectOk();
void recevierOKNGData(const QString&);
void recevierQrCodeData(const QString&);
void readComData();
void tryConnect();
private slots:
void on_conBtn_clicked();
void on_disConBtn_clicked();
void on_openBtn_clicked();
void on_closeBtn_clicked();
void on_conBtn_2_clicked();
void on_disConBtn_2_clicked();
private:
Ui::MainWindow *ui;
tcpClient *m_tcpClient, *m_tcpClient1;
SPComm *m_adam;
void readIpCfg();
void writeIpCfg();
QString decBin(long data);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#pragma execution_character_set("utf-8")
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
readIpCfg();
m_tcpClient = new tcpClient(this);
m_tcpClient->start();
m_tcpClient1 = new tcpClient(this);
m_tcpClient1->start();
m_adam = new SPComm();
QTimer* comT = new QTimer(this);
comT->start(200);
QTimer* connectT = new QTimer(this);
connectT->start(500);
m_tcpClient->tcpSocket->setObjectName("okng");
m_tcpClient1->tcpSocket->setObjectName("qrcode");
connect(m_tcpClient, &tcpClient::sendTcpMsg, this, &MainWindow::recevierOKNGData);
connect(m_tcpClient1, &tcpClient::sendTcpMsg, this, &MainWindow::recevierQrCodeData);
connect(m_tcpClient->tcpSocket,&QTcpSocket::connected, this, &MainWindow::connectOk);
connect(m_tcpClient->tcpSocket,&QTcpSocket::disconnected,this,&MainWindow::disConnectOk);
connect(m_tcpClient1->tcpSocket,&QTcpSocket::connected, this, &MainWindow::connectOk);
connect(m_tcpClient1->tcpSocket,&QTcpSocket::disconnected,this,&MainWindow::disConnectOk);
connect(this, &MainWindow::connectToTcp, m_tcpClient, &tcpClient::connectServer);
connect(this, &MainWindow::disConnectToTcp, m_tcpClient, &tcpClient::disConnectServer);
connect(this, &MainWindow::connectToTcp, m_tcpClient1, &tcpClient::connectServer);
connect(this, &MainWindow::disConnectToTcp, m_tcpClient1, &tcpClient::disConnectServer);
connect(comT, SIGNAL(timeout()), this , SLOT(readComData()));
connect(connectT, SIGNAL(timeout()), this , SLOT(tryConnect()));
}
MainWindow::~MainWindow()
{
m_tcpClient->setRun();
m_tcpClient->wait();
m_tcpClient1->setRun();
m_tcpClient1->wait();
delete m_adam;
delete ui;
}
void MainWindow::readIpCfg()
{
QSettings iniRead("C:/services/tcpokng/tcpConfig.ini", QSettings::IniFormat);
iniRead.beginGroup("com");
ui->comLE->setText(iniRead.value("port").toString());
iniRead.endGroup();
iniRead.beginGroup("tcpokng");
ui->iplineEdit->setText(iniRead.value("ip").toString());
ui->portlineEdit->setText(iniRead.value("port").toString());
iniRead.endGroup();
iniRead.beginGroup("tcpqrcode");
ui->iplineEdit_2->setText(iniRead.value("ip").toString());
ui->portlineEdit_2->setText(iniRead.value("port").toString());
iniRead.endGroup();
}
void MainWindow::writeIpCfg()
{
QSettings iniwrite("C:/services/tcpokng/tcpConfig.ini",QSettings::IniFormat);
iniwrite.beginGroup("com");
iniwrite.setValue("port",ui->comLE->text().trimmed());
iniwrite.endGroup();
iniwrite.beginGroup("tcpokng");
iniwrite.setValue("ip",ui->iplineEdit->text().trimmed());
iniwrite.setValue("port",ui->portlineEdit->text().trimmed());
iniwrite.endGroup();
iniwrite.beginGroup("tcpqrcode");
iniwrite.setValue("ip",ui->iplineEdit_2->text().trimmed());
iniwrite.setValue("port",ui->portlineEdit_2->text().trimmed());
iniwrite.endGroup();
}
void MainWindow::connectOk()
{
QString obj = QObject::sender()->objectName();
qDebug()<<obj;
if(obj == "okng")
{
ui->conBtn->setEnabled(false);
ui->disConBtn->setEnabled(true);
}
else if(obj == "qrcode")
{
ui->conBtn_2->setEnabled(false);
ui->disConBtn_2->setEnabled(true);
}
}
void MainWindow::disConnectOk()
{
QString obj = QObject::sender()->objectName();
if(obj == "okng")
{
ui->conBtn->setEnabled(true);
ui->disConBtn->setEnabled(false);
}
else if(obj == "qrcode")
{
ui->conBtn_2->setEnabled(true);
ui->disConBtn_2->setEnabled(false);
}
}
void MainWindow::recevierOKNGData(const QString& data)
{
//解析从OKNG获取到的JSON字符串
QJsonDocument doc = QJsonDocument::fromJson(data.toUtf8());
QJsonObject obj = doc.object();
auto iter = obj.find("panel");
auto iter1 = obj.find("ok");
if((iter != obj.end()) && (iter1 != obj.end()))
{
int panel = iter.value().toInt();
bool ok = iter1.value().toBool();
ui->textEdit->append(QString("From OKNG:%1->%2").arg(panel).arg(ok?"OK":"NG"));
if(panel == ui->qrValueLE->text().toInt())
{
std::string _signal;
if(ok)
_signal = "#01c010.000" + std::string("\x0d");
else
_signal = "#01c110.000" + std::string("\x0d");
m_adam->writeData(_signal);
ui->textEdit->append(QString("To Adam:%1").arg(QString::fromStdString(_signal).trimmed()));
}
}
}
void MainWindow::recevierQrCodeData(const QString& data)
{
//从读码器得到的当前面板数值
ui->qrValueLE->setText(data);
ui->textEdit->append(QString("From QrCode:%1").arg(data));
//发送给OKNG,获取结果
m_tcpClient->sendData(data.toStdString());
ui->textEdit->append(QString("To OKNG:%1").arg(data));
}
void MainWindow::readComData()
{
if(!m_adam->isOpen())
return;
QString data = m_adam->readData().trimmed();
if(!data.isEmpty())
{
ui->textEdit->append(QString("From Adam:%1").arg(data));
}
}
//To convert data into binary
QString MainWindow::decBin(long data)
{
long sum;
QString Sendata = "";
QString myStr = "";
int Lens;
sum = data;
while(sum > 0)
{
myStr = sum % 2;
sum = sum / 2;
Sendata += myStr;
}
// myStr = sum Mod 2
// sum = sum \ 2
// Sendata = Sendata & myStr
// Loop
// Lens = Sendata.length();
// Select Case Lens
// Case 1
// Sendata = Sendata & "000"
// Case 2
// Sendata = Sendata & "00"
// Case 3
// Sendata = Sendata & "0"
// Case 4
// Sendata = Sendata
// Case Else
// Sendata = "0000"
// End Select
// Sendata = StrReverse(Sendata)
// Return Sendata
return "";
}
void MainWindow::tryConnect()
{
on_conBtn_clicked();
on_conBtn_2_clicked();
on_openBtn_clicked();
}
void MainWindow::on_conBtn_clicked()
{
if(m_tcpClient->tcpSocket->state() == QAbstractSocket::ConnectedState)
return;
QString ip = ui->iplineEdit->text().trimmed();
int port = ui->portlineEdit->text().toInt();
this->setObjectName("okng");
emit connectToTcp(ip, port);
}
void MainWindow::on_disConBtn_clicked()
{
this->setObjectName("okng");
emit disConnectToTcp();
}
void MainWindow::on_openBtn_clicked()
{
if(m_adam->isOpen())
return;
m_adam->setBaudRate(9600);
m_adam->setPortName(ui->comLE->text().trimmed());
if(m_adam->open())
{
qDebug() << "打开串口成功";
ui->openBtn->setEnabled(false);
ui->closeBtn->setEnabled(true);
}
else
qWarning()<<"打开串口失败";
}
void MainWindow::on_closeBtn_clicked()
{
if(m_adam->isOpen())
{
m_adam->close();
qDebug()<<"关闭串口成功";
ui->closeBtn->setEnabled(false);
ui->openBtn->setEnabled(true);
}
}
void MainWindow::on_conBtn_2_clicked()
{
if(m_tcpClient1->tcpSocket->state() == QAbstractSocket::ConnectedState)
return;
QString ip = ui->iplineEdit_2->text().trimmed();
int port = ui->portlineEdit_2->text().toInt();
this->setObjectName("qrcode");
emit connectToTcp(ip, port);
}
void MainWindow::on_disConBtn_2_clicked()
{
this->setObjectName("qrcode");
emit disConnectToTcp();
}
void MainWindow::closeEvent(QCloseEvent *event)
{
m_adam->close();
this->setObjectName("okng");
emit disConnectToTcp();
this->setObjectName("qrcode");
emit disConnectToTcp();
writeIpCfg();
QMainWindow::closeEvent(event);
}
tcpClient.h
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <QObject>
#include <QTcpSocket>
#include <QTimer>
#include <QThread>
#include <filesystem>
#include <fstream>
class tcpClient : public QThread
{
Q_OBJECT
public:
tcpClient(QObject *parent=nullptr);
void setRun();
void sendData(std::string s);
QTcpSocket *tcpSocket = nullptr;
public slots:
void connectServer(QString&, int&);
void disConnectServer();
signals:
void sendTcpMsg(const QString&);
private:
void run();
bool m_run;
};
#endif // TCPCLIENT_H
tcpClient.cpp
#include "tcpclient.h"
tcpClient::tcpClient(QObject *parent):
QThread(parent)
{
m_run = true;
tcpSocket = new QTcpSocket(this);
}
void tcpClient::setRun()
{
m_run = false;
}
void tcpClient::run()
{
while(m_run)
{
if(tcpSocket->state() == QAbstractSocket::ConnectedState)
{
QString msg = tcpSocket->readLine();
if(!msg.isEmpty())
{
emit sendTcpMsg(msg);
}
}
msleep(200);
}
quit();
}
void tcpClient::sendData(std::string s)
{
if(tcpSocket->state() == QAbstractSocket::ConnectedState)
{
tcpSocket->write(s.c_str());
}
}
void tcpClient::connectServer(QString& ip, int& port)
{
if(tcpSocket->objectName() == sender()->objectName())
tcpSocket->connectToHost(ip, port);
}
void tcpClient::disConnectServer()
{
if(tcpSocket->objectName() == sender()->objectName())
tcpSocket->disconnectFromHost();
}
通过上面的试验可知:
1、槽函数的执行顺序和信号槽连接的顺序一致
2、首先利用 QObject::setObjectName(const QString&) 方法设置信号发出者的对象名称, 然后在槽函数中利用 QObject::sender()->objectName() 方法获取信号发出者的对象名称。
如需要源代码的话可私信本人,免费