點擊 <C 語言編程核心突破> 快速C語言入門
Qt學習總結
- 前言
- 二十 QTcpSocket QTcpServer網絡庫
- 服務端代碼:
- 客戶端代碼
- 二十一 QProcess進程類
- 二十二 QThread線程
- 總結
前言
要解決問題: 學習qt最核心知識, 多一個都不學.
二十 QTcpSocket QTcpServer網絡庫
QTcpSocket
和QTcpServer
網絡庫是QT框架提供的網絡編程庫之一,用于實現TCP協議的網絡通信。
下面是QTcpSocket
和QTcpServer
網絡庫中常用的C++函數:
QTcpSocket
常用函數:
QTcpSocket(QObject *parent = nullptr)
:構造函數。void connectToHost(const QString &hostName, quint16 port)
:連接到指定的主機名和端口。void disconnectFromHost()
:斷開與主機的連接。qint64 write(const char *data, qint64 maxSize)
:將數據寫入套接字。QByteArray read(qint64 maxSize)
:從套接字中讀取數據。bool waitForReadyRead(int msecs)
:等待套接字有可讀數據的信號。bool waitForConnected(int msecs)
:等待套接字成功連接到主機的信號。void flush()
:將寫入緩沖區的數據刷新到套接字。
QTcpServer
常用函數:
QTcpServer(QObject *parent = nullptr)
:構造函數。bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
:開始監聽指定的地址和端口。void close()
:關閉套接字,停止監聽。bool isListening() const
:判斷是否正在監聽。QTcpSocket *nextPendingConnection()
:獲取下一個掛起的連接。qintptr socketDescriptor() const
:獲取套接字的描述符。
以上是常用的QTcpSocket
和QTcpServer
網絡庫C++函數,其他函數可參考QT官方文檔。
示例:
關閉客戶端, 再開啟客戶端連接, 發送信息
服務端代碼:
Widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QTcpServer>
#include <QTcpSocket>
#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_cancelButton_clicked();void on_sendButton_clicked();public slots:void connectHandler();void reciveText();private:Ui::Widget *ui;QTcpServer *qtServer;QTcpSocket *qtSocket;
};
#endif // WIDGET_H
main.cpp
#include "Widget.h"#include <QApplication>
#include <QLocale>
#include <QTranslator>int main(int argc, char *argv[])
{QApplication a(argc, argv);QTranslator translator;const QStringList uiLanguages = QLocale::system().uiLanguages();for (const QString &locale : uiLanguages) {const QString baseName = "Learn_18_" + QLocale(locale).name();if (translator.load(":/i18n/" + baseName)) {a.installTranslator(&translator);break;}}Widget w;w.show();return a.exec();
}
Widget.cpp
#include "Widget.h"
#include "./ui_Widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), qtServer(new QTcpServer), qtSocket(nullptr)
{ui->setupUi(this);qtServer->listen(QHostAddress::AnyIPv4, 8000);connect(qtServer, SIGNAL(newConnection()), this, SLOT(connectHandler()));
}Widget::~Widget()
{delete ui;qtServer->close();if (qtSocket != nullptr){qtSocket->close();}
}void Widget::on_cancelButton_clicked()
{this->close();
}void Widget::connectHandler()
{if (qtSocket != nullptr){qtSocket->disconnect();qtSocket->disconnectFromHost();qtSocket->close();}qtSocket = qtServer->nextPendingConnection();ui->ipLineEdit->setText(qtSocket->peerAddress().toString());ui->portLineEdit->setText(QString::number(qtSocket->peerPort()));connect(qtSocket, SIGNAL(readyRead()), this, SLOT(reciveText()));connect(qtSocket, &QTcpSocket::disconnected,[this]() { qDebug() << "Disconnected"; });
}void Widget::reciveText()
{ui->reciveLineEdit->setText(QString(qtSocket->readAll()));
}void Widget::on_sendButton_clicked()
{if (qtSocket->isValid()){qtSocket->write(ui->sendLineEdit->text().toUtf8());}else{qDebug() << "unconnect";}
}
ui_Widget.h
/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/#ifndef UI_WIDGET_H
#define UI_WIDGET_H#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>QT_BEGIN_NAMESPACEclass Ui_Widget
{
public:QLabel *label_5;QWidget *widget;QFormLayout *formLayout;QLabel *label;QLineEdit *ipLineEdit;QLabel *label_2;QLineEdit *portLineEdit;QLabel *label_3;QLineEdit *reciveLineEdit;QLabel *label_4;QLineEdit *sendLineEdit;QWidget *widget1;QHBoxLayout *horizontalLayout;QPushButton *sendButton;QPushButton *cancelButton;void setupUi(QWidget *Widget){if (Widget->objectName().isEmpty())Widget->setObjectName("Widget");Widget->resize(482, 419);label_5 = new QLabel(Widget);label_5->setObjectName("label_5");label_5->setGeometry(QRect(190, 20, 92, 50));label_5->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));widget = new QWidget(Widget);widget->setObjectName("widget");widget->setGeometry(QRect(10, 90, 461, 220));formLayout = new QFormLayout(widget);formLayout->setObjectName("formLayout");formLayout->setContentsMargins(0, 0, 0, 0);label = new QLabel(widget);label->setObjectName("label");label->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(0, QFormLayout::LabelRole, label);ipLineEdit = new QLineEdit(widget);ipLineEdit->setObjectName("ipLineEdit");ipLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(0, QFormLayout::FieldRole, ipLineEdit);label_2 = new QLabel(widget);label_2->setObjectName("label_2");label_2->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(1, QFormLayout::LabelRole, label_2);portLineEdit = new QLineEdit(widget);portLineEdit->setObjectName("portLineEdit");portLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(1, QFormLayout::FieldRole, portLineEdit);label_3 = new QLabel(widget);label_3->setObjectName("label_3");label_3->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(2, QFormLayout::LabelRole, label_3);reciveLineEdit = new QLineEdit(widget);reciveLineEdit->setObjectName("reciveLineEdit");reciveLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(2, QFormLayout::FieldRole, reciveLineEdit);label_4 = new QLabel(widget);label_4->setObjectName("label_4");label_4->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(3, QFormLayout::LabelRole, label_4);sendLineEdit = new QLineEdit(widget);sendLineEdit->setObjectName("sendLineEdit");sendLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(3, QFormLayout::FieldRole, sendLineEdit);widget1 = new QWidget(Widget);widget1->setObjectName("widget1");widget1->setGeometry(QRect(10, 330, 461, 54));horizontalLayout = new QHBoxLayout(widget1);horizontalLayout->setObjectName("horizontalLayout");horizontalLayout->setContentsMargins(0, 0, 0, 0);sendButton = new QPushButton(widget1);sendButton->setObjectName("sendButton");sendButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));horizontalLayout->addWidget(sendButton);cancelButton = new QPushButton(widget1);cancelButton->setObjectName("cancelButton");cancelButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));horizontalLayout->addWidget(cancelButton);retranslateUi(Widget);QMetaObject::connectSlotsByName(Widget);} // setupUivoid retranslateUi(QWidget *Widget){Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));label_5->setText(QCoreApplication::translate("Widget", "\346\234\215\345\212\241\347\253\257", nullptr));label->setText(QCoreApplication::translate("Widget", "IP\345\234\260\345\235\200", nullptr));label_2->setText(QCoreApplication::translate("Widget", "\347\253\257\345\217\243\345\217\267", nullptr));label_3->setText(QCoreApplication::translate("Widget", "\346\224\266 \346\226\207", nullptr));label_4->setText(QCoreApplication::translate("Widget", "\345\217\221 \346\226\207", nullptr));sendButton->setText(QCoreApplication::translate("Widget", "\345\217\221\351\200\201", nullptr));cancelButton->setText(QCoreApplication::translate("Widget", "\345\217\226\346\266\210", nullptr));} // retranslateUi};namespace Ui {class Widget: public Ui_Widget {};
} // namespace UiQT_END_NAMESPACE#endif // UI_WIDGET_H
客戶端代碼
Widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QTcpSocket>
#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_linkButton_clicked();void on_sendButton_clicked();void on_cancelButton_clicked();public slots:void recieveText();private:Ui::Widget *ui;QTcpSocket *socket;
};
#endif // WIDGET_H
main.cpp
#include "Widget.h"#include <QApplication>
#include <QLocale>
#include <QTranslator>int main(int argc, char *argv[])
{QApplication a(argc, argv);QTranslator translator;const QStringList uiLanguages = QLocale::system().uiLanguages();for (const QString &locale : uiLanguages) {const QString baseName = "Learn_19_" + QLocale(locale).name();if (translator.load(":/i18n/" + baseName)) {a.installTranslator(&translator);break;}}Widget w;w.show();return a.exec();
}
Widget.cpp
#include "Widget.h"
#include "./ui_Widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), socket(new QTcpSocket)
{ui->setupUi(this);connect(socket, &QTcpSocket::connected, [this]() { qDebug() << "OK"; });connect(socket, SIGNAL(readyRead()), this, SLOT(recieveText()));connect(socket, &QTcpSocket::disconnected,[this]() { qDebug() << "Disconnected"; });
}Widget::~Widget()
{delete ui;
}void Widget::on_linkButton_clicked()
{// socket->disconnect();QString ipAdd(ui->ipLineEdit->text());socket->connectToHost(QHostAddress(ipAdd),ui->portLineEdit->text().toUShort());
}void Widget::on_sendButton_clicked()
{if (socket->isValid()){socket->write(ui->sendLineEdit->text().toUtf8());}
}void Widget::on_cancelButton_clicked()
{this->close();
}void Widget::recieveText()
{QString res = QString::fromUtf8(socket->readAll());ui->recieveLineEdit->setText(res);qDebug() << res;
}
ui_Widget.h
/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/#ifndef UI_WIDGET_H
#define UI_WIDGET_H#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>QT_BEGIN_NAMESPACEclass Ui_Widget
{
public:QLabel *label_5;QWidget *layoutWidget;QFormLayout *formLayout;QLabel *label;QLineEdit *ipLineEdit;QLabel *label_2;QLineEdit *portLineEdit;QLabel *label_3;QLineEdit *sendLineEdit;QLabel *label_4;QLineEdit *recieveLineEdit;QWidget *layoutWidget1;QHBoxLayout *horizontalLayout;QPushButton *linkButton;QPushButton *sendButton;QPushButton *cancelButton;void setupUi(QWidget *Widget){if (Widget->objectName().isEmpty())Widget->setObjectName("Widget");Widget->resize(555, 400);label_5 = new QLabel(Widget);label_5->setObjectName("label_5");label_5->setGeometry(QRect(220, 10, 101, 50));label_5->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));layoutWidget = new QWidget(Widget);layoutWidget->setObjectName("layoutWidget");layoutWidget->setGeometry(QRect(10, 80, 541, 220));formLayout = new QFormLayout(layoutWidget);formLayout->setObjectName("formLayout");formLayout->setContentsMargins(0, 0, 0, 0);label = new QLabel(layoutWidget);label->setObjectName("label");label->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(0, QFormLayout::LabelRole, label);ipLineEdit = new QLineEdit(layoutWidget);ipLineEdit->setObjectName("ipLineEdit");ipLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(0, QFormLayout::FieldRole, ipLineEdit);label_2 = new QLabel(layoutWidget);label_2->setObjectName("label_2");label_2->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(1, QFormLayout::LabelRole, label_2);portLineEdit = new QLineEdit(layoutWidget);portLineEdit->setObjectName("portLineEdit");portLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(1, QFormLayout::FieldRole, portLineEdit);label_3 = new QLabel(layoutWidget);label_3->setObjectName("label_3");label_3->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(2, QFormLayout::LabelRole, label_3);sendLineEdit = new QLineEdit(layoutWidget);sendLineEdit->setObjectName("sendLineEdit");sendLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(2, QFormLayout::FieldRole, sendLineEdit);label_4 = new QLabel(layoutWidget);label_4->setObjectName("label_4");label_4->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(3, QFormLayout::LabelRole, label_4);recieveLineEdit = new QLineEdit(layoutWidget);recieveLineEdit->setObjectName("recieveLineEdit");recieveLineEdit->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(3, QFormLayout::FieldRole, recieveLineEdit);layoutWidget1 = new QWidget(Widget);layoutWidget1->setObjectName("layoutWidget1");layoutWidget1->setGeometry(QRect(10, 330, 531, 54));horizontalLayout = new QHBoxLayout(layoutWidget1);horizontalLayout->setObjectName("horizontalLayout");horizontalLayout->setContentsMargins(0, 0, 0, 0);linkButton = new QPushButton(layoutWidget1);linkButton->setObjectName("linkButton");linkButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));horizontalLayout->addWidget(linkButton);sendButton = new QPushButton(layoutWidget1);sendButton->setObjectName("sendButton");sendButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));horizontalLayout->addWidget(sendButton);cancelButton = new QPushButton(layoutWidget1);cancelButton->setObjectName("cancelButton");cancelButton->setStyleSheet(QString::fromUtf8("font: 700 24pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));horizontalLayout->addWidget(cancelButton);retranslateUi(Widget);QMetaObject::connectSlotsByName(Widget);} // setupUivoid retranslateUi(QWidget *Widget){Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));label_5->setText(QCoreApplication::translate("Widget", "\345\256\242\346\210\267\347\253\257", nullptr));label->setText(QCoreApplication::translate("Widget", "IP", nullptr));ipLineEdit->setText(QCoreApplication::translate("Widget", "127.0.0.1", nullptr));label_2->setText(QCoreApplication::translate("Widget", "\347\253\257\345\217\243", nullptr));portLineEdit->setText(QCoreApplication::translate("Widget", "8000", nullptr));label_3->setText(QCoreApplication::translate("Widget", "\345\217\221\351\200\201", nullptr));label_4->setText(QCoreApplication::translate("Widget", "\346\216\245\346\224\266", nullptr));linkButton->setText(QCoreApplication::translate("Widget", "\350\277\236\346\216\245", nullptr));sendButton->setText(QCoreApplication::translate("Widget", "\345\217\221\351\200\201", nullptr));cancelButton->setText(QCoreApplication::translate("Widget", "\345\217\226\346\266\210", nullptr));} // retranslateUi};namespace Ui {class Widget: public Ui_Widget {};
} // namespace UiQT_END_NAMESPACE#endif // UI_WIDGET_H
通常在建立qt項目時, 不會自動鏈接Network
頭文件及庫文件, 需要在cmake
文件中加入:
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Network)
target_link_libraries(Learn_18 PRIVATE Qt${QT_VERSION_MAJOR}::Network)
其中Learn_18
是項目名, 根據你的項目更改.
二十一 QProcess進程類
QProcess
是一個進程管理類,它允許您啟動外部程序和與它們通信。
QProcess支持同步和異步啟動,也可以使用管道和I / O重定向向子進程發送和接收數據。
下面是常用函數列表:
-
QProcess(const QStringList &arguments = QStringList(), QObject *parent = nullptr)
該函數可以創建一個用于啟動外部程序的QProcess
對象,可以設置啟動參數。 -
setProgram(QString program)
設置要啟動的程序或可執行文件的路徑。 -
setArguments(const QStringList &arguments)
設置啟動參數列表。 -
setWorkingDirectory(QString dir)
設置運行外部程序的工作目錄。 -
start(const QString &program, const QStringList &arguments = {}, OpenMode mode = ReadWrite);
啟動外部程序。 -
waitForStarted(int msecs = 30000)
等待外部程序啟動,返回true
表示啟動成功,false
表示啟動失敗。 -
waitForFinished(int msecs = 30000)
等待外部程序執行完成,返回true表示執行完成,false
表示超時或執行失敗。 -
readAllStandardOutput()
讀取外部程序的標準輸出,返回一個QByteArray
。 -
readAllStandardError()
讀取外部程序的標準錯誤輸出,返回一個QByteArray
。 -
void write(const QByteArray &byteArray)
向外部程序的標準輸入寫入數據。
您還可以使用QIODevice
API通過管道與子進程通信。
常見的用法是通過標準輸入輸出管道或錯誤輸出管道發送和接收數據。
您還可以使用readAllStandardOutput()
和readAllStandardError()
函數來獲取進程的輸出和錯誤輸出。
在非Windows
平臺上,QProcess
使用QAbstractEventDispatcher
來監視子進程。
使用QProcess
的事件循環時,如果有進程事件到達,將調用QProcess
的虛擬函數來處理該事件。
如果使用waitForStarted()
或waitForFinished()
之類的功能等待進程,則QProcess
將在事件循環內等待進程事件的到來。
在Windows
上,QProcess
使用WaitHandle
實現進程監視,并且可以兼容在Windows上
使用其他Qt的進程相關類。
示例:
用進程類實現一個應用, 當點擊run
, 從命令和參數文本框獲取命令文本, 并啟動進程, 將結果返回到結果文本框中.
Widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QProcess>
#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_runButton_clicked();private:Ui::Widget *ui;
};
#endif // WIDGET_H
main.cpp
#include "Widget.h"#include <QApplication>
#include <QLocale>
#include <QTranslator>int main(int argc, char *argv[])
{QApplication a(argc, argv);QTranslator translator;const QStringList uiLanguages = QLocale::system().uiLanguages();for (const QString &locale : uiLanguages) {const QString baseName = "Learn_20_" + QLocale(locale).name();if (translator.load(":/i18n/" + baseName)) {a.installTranslator(&translator);break;}}Widget w;w.show();return a.exec();
}
Widget.cpp
#include "Widget.h"
#include "./ui_Widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_runButton_clicked()
{QProcess process(this);QStringList qsl;qsl << ui->optionLineEdit->text();process.start(ui->commendLineEdit->text(), qsl);if (process.waitForStarted() && process.waitForFinished()){qDebug() << "OK";}QByteArray output = process.readAllStandardOutput();ui->resultTextEdit->setText(QString::fromLocal8Bit(output));qDebug() << QString::fromLocal8Bit(output);
}
ui_Widget.h
/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/#ifndef UI_WIDGET_H
#define UI_WIDGET_H#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QWidget>QT_BEGIN_NAMESPACEclass Ui_Widget
{
public:QPushButton *runButton;QTextEdit *resultTextEdit;QWidget *layoutWidget;QFormLayout *formLayout;QLabel *label;QLabel *label_2;QLineEdit *commendLineEdit;QLineEdit *optionLineEdit;void setupUi(QWidget *Widget){if (Widget->objectName().isEmpty())Widget->setObjectName("Widget");Widget->resize(508, 577);runButton = new QPushButton(Widget);runButton->setObjectName("runButton");runButton->setGeometry(QRect(10, 530, 81, 31));runButton->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));resultTextEdit = new QTextEdit(Widget);resultTextEdit->setObjectName("resultTextEdit");resultTextEdit->setGeometry(QRect(10, 90, 491, 421));layoutWidget = new QWidget(Widget);layoutWidget->setObjectName("layoutWidget");layoutWidget->setGeometry(QRect(10, 10, 491, 72));formLayout = new QFormLayout(layoutWidget);formLayout->setObjectName("formLayout");formLayout->setContentsMargins(0, 0, 0, 0);label = new QLabel(layoutWidget);label->setObjectName("label");label->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(0, QFormLayout::LabelRole, label);label_2 = new QLabel(layoutWidget);label_2->setObjectName("label_2");label_2->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(0, QFormLayout::FieldRole, label_2);commendLineEdit = new QLineEdit(layoutWidget);commendLineEdit->setObjectName("commendLineEdit");commendLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(1, QFormLayout::LabelRole, commendLineEdit);optionLineEdit = new QLineEdit(layoutWidget);optionLineEdit->setObjectName("optionLineEdit");optionLineEdit->setStyleSheet(QString::fromUtf8("font: 700 16pt \"\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B\";"));formLayout->setWidget(1, QFormLayout::FieldRole, optionLineEdit);retranslateUi(Widget);QMetaObject::connectSlotsByName(Widget);} // setupUivoid retranslateUi(QWidget *Widget){Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));runButton->setText(QCoreApplication::translate("Widget", "run", nullptr));label->setText(QCoreApplication::translate("Widget", "\345\221\275\344\273\244", nullptr));label_2->setText(QCoreApplication::translate("Widget", "\345\217\202\346\225\260", nullptr));} // retranslateUi};namespace Ui {class Widget: public Ui_Widget {};
} // namespace UiQT_END_NAMESPACE#endif // UI_WIDGET_H
二十二 QThread線程
QThread
是Qt框架中的線程類,它提供了一個跨平臺的線程類庫,可以在Qt應用程序中實現多線程編程,實現并發執行任務的能力。
QThread
類通過繼承QThread
并重載run()
函數來實現自己的線程。
run()
函數中包含了線程的邏輯代碼,線程啟動時會自動調用run()
函數。
QThread
還提供了一些常用的函數,如start()
函數開始線程,quit()
函數結束線程,wait()
函數等待線程結束等。
常用函數:
start()
:啟動線程,該函數將會調用run()
函數;
sleep()
:暫停當前線程,單位毫秒;
quit()
:結束線程,類似于Thread
類的Stop
方法;
wait()
:等待當前線程執行完畢,阻塞當前線程;
finished()
:當線程執行結束時會發出該信號;
terminate()
:強制關閉線程,類似于Thread
類的Abort
方法。
C++示例:用線程返回相加結果, 并在主線程輸出
我們實現一個myThread
線程類, 繼承自QThread
, 當觸發計算時, 調用槽函數, 生成線程, 線程運算相加結果, 并通過信號槽機制返回給主線程, 進行顯示.
myThread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QThread>class myThread : public QThread
{Q_OBJECTpublic:explicit myThread(QObject *parent = nullptr, int numA_ = 0, int numB_ = 0);void run() override;signals:void result(int);private:int numA;int numB;
};#endif // MYTHREAD_H
myThread.cpp
#include "myThread.h"myThread::myThread(QObject *parent, int numA_, int numB_): QThread{parent}, numA(numA_), numB(numB_)
{}void myThread::run()
{emit result(numA + numB);
}
通過簡單的封裝, 可以很容易的將數據傳給線程, 通過信號槽機制, 又很容易的可以將結果返回, 相比C或C++原生thread
, 已經人性化的一塌糊度了.
當然, 效率問題不在本文探討之列.
Widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();public slots:void getResult(int res);private slots:void on_pushButton_clicked();private:Ui::Widget *ui;
};
#endif // WIDGET_H
Widget.cpp
#include "Widget.h"
#include "./ui_Widget.h"
#include "myThread.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{int numA = ui->lineEditA->text().toInt();int numB = ui->lineEditB->text().toInt();myThread *qthrd = new myThread(this, numA, numB);qthrd->start();connect(qthrd, SIGNAL(result(int)), this, SLOT(getResult(int)));qthrd->wait();qthrd->deleteLater();
}void Widget::getResult(int res)
{ui->lineEditSum->setText(QString::number(res));
}
總結
二十 QTcpSocket QTcpServer網絡庫
服務端代碼:
客戶端代碼
二十一 QProcess進程類
二十二 QThread線程
點擊 <C 語言編程核心突破> 快速C語言入門