跳到主要内容

Qt

Qt官网

一个代码库
有很多很多可以直接使用的功能
例如线程池,网络编程等等
支持很多语言,例如C++


安装

最好下载在线安装器
因为在线库很乱,手动找很麻烦

  1. 去Qt官网下载开源版本在线安装器
  2. 使用命令行qt安装器路径.exe --mirror https://mirrors.aliyun.com/qt/
  3. 选择需要的模块进行安装

minGW好像不能通过Qt直接安装吧大概
不说这个,minGW的版本必须与Qt的版本对应
否则会出现一些灾难性的错误
编译器可以选择minGW和MSVC
最好选MSVC

Vscode

需要安装Qt toolsQt Configure两个插件

MSVC,minGW均可使用Qt,看喜好选择

CMake配置

具体参阅Qt的官方文档

注意编译脚本(CMake)中Qt的路径和版本

需要用什么模块就引入什么模块

CMake也是一坨构室


※疑难杂症

使用控制台进行输入输出

# CMake
add_executable(${PROJECT_NAME}

WIN32 # 注释掉这一行
# 原文: If you need a terminal for debug, please comment this statement
${srcs}
)
set_target_properties(${PROJECT_NAME} PROPERTIES
WIN32_EXECUTABLE OFF # 这一行改为OFF
MACOSX_BUNDLE ON
)
// c++ code
QTextStream* qIn = new QTextStream(stdin);
QString str;
while (true) {
str = qIn->readLine();
if (!str.isEmpty()) {
// code here
}
}

使用Meta-Object Complier(MOC)

这个是当你声明了一个继承了QObject的子类
使用了自定义信号和槽(与之相伴的必须添加Q_OBJECT宏定义)
但是编译器并不知道这个类中有信号和槽
所以需要使用MOC来处理这个类
让编译器知道这个类中有信号和槽

声明在头文件中
// Func.h
#pragma once
#include "../cpphead.h"

class InputThread : public QThread {
Q_OBJECT//宏定义
public:
InputThread(QObject* p = nullptr);
void run() override;
signals:
void input(QString str);
};
// Func.cpp
#include "head/cpphead.h"

InputThread::InputThread(QObject* p) : QThread(p) {}

void InputThread::run() {
QTextStream* qIn = new QTextStream(stdin);
QString str;
while (true) {
str = qIn->readLine();
if (!str.isEmpty()) {
emit input(str);
}
}
}

#include "moc_Func.cpp" //关键是这一行,moc_name.cpp
声明和定义都在源文件中
// Func.cpp
#include "head/cpphead.h"
class InputThread : public QThread {
Q_OBJECT//宏定义
public:
InputThread(QObject* p = nullptr) : QThread(p) {};
void run() override {
QTextStream* qIn = new QTextStream(stdin);
QString str;
while (true) {
str = qIn->readLine();
if (!str.isEmpty()) {
emit input(str);
}
}
}
signals:
void input(QString str);
};

#include "Func.moc"//这一行

QTcpSocket多线程

QTcpSocket无法原生在其他线程调用

//关键是第三个参数,要写槽函数所在的对象,这样才会把信号从A线程发送到B线程,然后在B线程调用槽函数
QObject::connect(inputThread, &InputThread::input, messageServer, [=](QString str) {
for (QTcpSocket* tcpSocket : *messageServer->tcpSockets) {
str = "server:" + str;
messageServer->sendData(tcpSocket, str);
}
});