2023-12-05 Qt学习总结7_ QTcpSocket QTcpServer网络库_QProcess进程类_QThread线程


点击 <C 语言编程核心突破> 快速C语言入门



前言

要解决问题: 学习qt最核心知识, 多一个都不学.


二十 QTcpSocket QTcpServer网络库

QTcpSocketQTcpServer网络库是QT框架提供的网络编程库之一,用于实现TCP协议的网络通信。

下面是QTcpSocketQTcpServer网络库中常用的C++函数:

QTcpSocket常用函数:

  1. QTcpSocket(QObject *parent = nullptr):构造函数。
  2. void connectToHost(const QString &hostName, quint16 port):连接到指定的主机名和端口。
  3. void disconnectFromHost():断开与主机的连接。
  4. qint64 write(const char *data, qint64 maxSize):将数据写入套接字。
  5. QByteArray read(qint64 maxSize):从套接字中读取数据。
  6. bool waitForReadyRead(int msecs):等待套接字有可读数据的信号。
  7. bool waitForConnected(int msecs):等待套接字成功连接到主机的信号。
  8. void flush():将写入缓冲区的数据刷新到套接字。

QTcpServer常用函数:

  1. QTcpServer(QObject *parent = nullptr):构造函数。
  2. bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0):开始监听指定的地址和端口。
  3. void close():关闭套接字,停止监听。
  4. bool isListening() const:判断是否正在监听。
  5. QTcpSocket *nextPendingConnection():获取下一个挂起的连接。
  6. qintptr socketDescriptor() const:获取套接字的描述符。

以上是常用的QTcpSocketQTcpServer网络库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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    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_NAMESPACE

class 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);
    } // setupUi

    void 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 Ui

QT_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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    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_NAMESPACE

class 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);
    } // setupUi

    void 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 Ui

QT_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重定向向子进程发送和接收数据。

下面是常用函数列表:

  1. QProcess(const QStringList &arguments = QStringList(), QObject *parent = nullptr) 该函数可以创建一个用于启动外部程序的QProcess对象,可以设置启动参数。

  2. setProgram(QString program) 设置要启动的程序或可执行文件的路径。

  3. setArguments(const QStringList &arguments) 设置启动参数列表。

  4. setWorkingDirectory(QString dir) 设置运行外部程序的工作目录。

  5. start(const QString &program, const QStringList &arguments = {}, OpenMode mode = ReadWrite); 启动外部程序。

  6. waitForStarted(int msecs = 30000) 等待外部程序启动,返回true表示启动成功,false表示启动失败。

  7. waitForFinished(int msecs = 30000) 等待外部程序执行完成,返回true表示执行完成,false表示超时或执行失败。

  8. readAllStandardOutput() 读取外部程序的标准输出,返回一个QByteArray

  9. readAllStandardError() 读取外部程序的标准错误输出,返回一个QByteArray

  10. 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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    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_NAMESPACE

class 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);
    } // setupUi

    void 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 Ui

QT_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_OBJECT
  public:
    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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

  public:
    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语言入门


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不停感叹的老林_<C 语言编程核心突破>

不打赏的人, 看完也学不会.

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值