Qt
一个代码库
有很多很多可以直接使用的功能
例如线程池,网络编程等等
支持很多语言,例如C++
安装
最好下载在线安装器
因为在线库很乱,手动找很麻烦
- 去Qt官网下载开源版本在线安装器
- 使用命令行
qt安装器路径.exe --mirror https://mirrors.aliyun.com/qt/
- 选择需要的模块进行安装
minGW好像不能通过Qt直接安装吧大概
不说这个,minGW的版本必须与Qt的版本对应
否则会出现一些灾难性的错误
编译器可以选择minGW和MSVC
最好选MSVC
Vscode
需要安装Qt tools和Qt 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);
}
});