RGB 颜色对照表


1
2
3
4
5
6
7
8
9
#include <QPushButton>  //调用按钮头文件
/*选择组合*/
QPushButton *bt; //这里构造一个指针
this->setFixedSize(640, 480); //设置页面
bt = new QPushButton("登录", this); //构造一个按钮对象
bt->setGeometry(300, 400, 100, 50); //设置按钮坐标
//bt->setStyleSheet("QPushButton{color:blue;};"); //设置风格;设置字体颜色蓝色
//bt->setStyleSheet("QPushButton{background-color:blue;};"); //设置风格;设置登录框背景显示蓝色
bt->setStyleSheet("QPushButton{background-color:#63B8FF;};"); //设置风格;设置登录可以根据颜色码表设置颜色蓝色

# 1.QT 工程示例

基础模板(QWidget/QDialog/QMainWindow)
(1) 信号
当信号被发射时,QT 代码将回调与其相连接的槽函数
信号将由元对象处理 moc 自动翻译成 C 代码
信号的声明不在 cpp 文件中,而在头文件中
(2) 槽函数
槽函数是普通的 C
成员函数,可以被正常调用
槽函数可以有返回值,也可以没有
槽函数的访问权限三种: public slots、 private slots 和 protected
slots。槽函数的存取权限决定了谁能够与其相关联
##QT 程序的打包
1. 找到 filename.exe 文件
2.QT 编译器 windeployqt.exe filename.exe
本方法打包程序较大,包含.dll 等库文件,详见 8.4


# 2.QT 组件

# 2.1QT 对话框

  • 文件对话框 (QFile Dialog)
  • 消息对话框 (QMessageBox)
  • 输入对话框 (QInputDialog)
  • 颜色对话框 (QColorDialog)
  • 字体对话框 (QFontDialog)

# 2.1.1 文件对话框

#
1
2
3
4
5
6
7
8
9
10
 //文件对话框示例
connect(bt_filename, &QPushButton::clicked, [&](){
//提取单个文件名的对话框
// QString filename = QFileDialog::getOpenFileName();
// te_test->append(filename);
//提取多个文件名的对话框
QStringList filenames = QFileDialog::getOpenFileNames(this, "打开图片", ".", "Images (*.png *.xpm *.jpg)");
for(int i=0; i<filenames.length(); i++)
te_test->append(filenames[i]);
});

# 2.1.2 颜色对话框

#
1
2
3
4
5
//颜色对话框示例
connect(bt_getcolor, &QPushButton::clicked, [&](){
QColor color = QColorDialog::getColor();
te_test->setTextColor(color);
});

# 2.1.3 字体对话框

#
1
2
3
4
5
6
7
8
//字体对话框示例
connect(bt_getfont, &QPushButton::clicked, [&](){
bool ok;
QFont font = QFontDialog::getFont(&ok);

if(ok) //用户选择了字体
te_test->setCurrentFont(font);
});

# 2.1.4 输入对话框

#
1
2
3
4
5
//输入对话框示例
connect(bt_getinput, &QPushButton::clicked, [&](){
QString str = QInputDialog::getText(this, "xxxx", "yyyy");
te_test->setText(str);
});

# 2.1.5 消息对话框

1
2
3
4
//消息弹窗示例
connect(bt_message, &QPushButton::clicked, [&](){
QMessageBox::warning(this, "xxxx", "yyyyyyy", QMessageBox::Open, QMessageBox::Apply);
});

# 2.1.6 错误消息对话框

#
1
2
3
4
5
//错误弹窗示例
connect(bt_error, &QPushButton::clicked, [&](){
QErrorMessage *x;
x->showMessage("xxxxxxxxxxxxxxxxxxx");
});

# 2.1.7 进度条

#
1
2
3
4
5
6
//进度条对话框示例
connect(bt_progress, &QPushButton::clicked, [&](){
QProgressDialog x;
x.setValue(88);
x.exec();
});

# 2.2QT 内置组件

# 2.2.1 按钮 QPushButton

1
connect(ui->pushButton,SIGNAL(clicked()),ui->lineEdit,SLOT(clea()));//clicked()信号

###2.2.2 标签 QLabel
1
2
3
4
5
6
7
8
9
10
#include <QDebug> //打印头文件
//2.QLabel组件显示文本
ui->labelPic->setText("ssssss");//设置label组件的文本
qDebug() << ui->labelPic->text();//获取label组件的文本内容

//3.QLabel显示图片
QPixmap pixmap;//装像素的容器
pixmap.load("D:/Personal/Embedded/QT/210901/211103/label2.jpg");//等价:pixmap.load("E:\\21091\\images\\cat.jpg");
ui->labelPic->setPixmap(pixmap);//label显示图片
ui->labelPic->setScaledContents(true);//内容自适应

# 2.2.3 单选按钮 radioButton

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Widget::on_radioButton_clicked()   //A
{
if(ui->radioButton->isChecked())//radioButton是否被选中
{
ui->radioButton_2->setChecked(false);//radio2不被选中
}
else
ui->radioButton_2->setChecked(true);
}
void Widget::on_radioButton_2_clicked() //B
{
if(ui->radioButton_2->isChecked())//radioButton_2是否被选中
{
ui->radioButton->setChecked(false);//radio不被选中
}
else
ui->radioButton->setChecked(true);
}

# 2.2.4 复选框 QCheckBox

1
2
3
4
5
6
7
8
9
#include <QDebug>
void Widget::on_checkBox_stateChanged(int arg1)
{
qDebug() << arg1;
}
void Widget::on_checkBox_2_stateChanged(int arg1)
{
qDebug() << arg1;
}

# 2.2.5 列表框 QListWidget

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//5.QListWidget列表组件(qq wechat等的联系人列表)
ui->listWidget->addItem("BBB"); //动态给listWidget中添加列表项item
ui->listWidget->addItem(new QListWidgetItem(QIcon("D:/Personal/Embedded/QT/210901/211103/薯条.png"),"AAA"));//动态给listWidget中添加列表项item并设置图标
ui->listWidget->sortItems();//升序排序
// 左右移动
void Widget::on_pushButtonRight_clicked() //实现左边的listWidget中的item移动到右边的listWidget_2中
{
QListWidgetItem *item ;
item = ui->listWidget->takeItem(ui->listWidget->currentRow());//删除当前选中的列表项
ui->listWidget_2->addItem(item);//将item添加到listwidget_2中
ui->listWidget->sortItems();
ui->listWidget_2->sortItems();
}

void Widget::on_pushButtonLeft_clicked() //实现右边的listWidget_2中的item移动到左边的listWidget中
{
QListWidgetItem *item ;
item = ui->listWidget_2->takeItem(ui->listWidget_2->currentRow());//删除当前选中的列表项
ui->listWidget->addItem(item);//将item添加到listwidget中
ui->listWidget->sortItems();
ui->listWidget_2->sortItems();
}

# 2.2.6 组合框 ComboBox

1
2
3
//6.QComboBox下拉列表组件(例如:12306选择始发地 目的地等)
ui->comboBox->addItem("北京");//动态给comboBox组件添加列表项
ui->comboBox->addItem(QIcon(":/images/上海.png"),"上海"); //资源文件路径格式

# 2.2.7 自旋框 QSpinBox

1
2
3
4
5
6
7
8
9
10
11
12
//7.QSpinBox自旋框组件
ui->spinBox->setValue(5);//设置spinbox的值

void Widget::on_spinBox_valueChanged(const QString &arg1)
{
qDebug() << arg1; //spinbox的值
}

void Widget::on_spinBox_valueChanged(int arg1)
{
qDebug() << arg1; //spinbox的值
}

# 2.2.8 滑动条 SLider

1
2
3
4
5
6
7
8
9
10
11
//8.QHorizontal Slider 水平滑动条组件
ui->horizontalSlider->setValue(25);//设置滑动条的值
void Widget::on_horizontalSlider_sliderMoved(int position)
{
qDebug() << position; //当前滑块的位置
}
void Widget::on_horizontalSlider_valueChanged(int value)
{
qDebug() << value;//当前滑块所在位置的值
ui->progressBar->setValue(value);
}

# 2.2.9 进度条 QProgressBox

1
2
3
4
5
6
//9.QProgress Bar进度条组件
ui->progressBar->setValue(25);
void Widget::on_progressBar_valueChanged(int value)
{
//编辑功能
}

# 2.2.10 行编辑器 QLineEdit

1
2
3
4
5
//10.QLineEdit行编辑器组件
ui->lineEditName->setText("xiaoming");
ui->lineEditPasswd->setEchoMode(QLineEdit::Password);//密码方式显示密码
ui->lineEditPasswd->setMaxLength(8);//密码长度最大为8
qDebug() << ui->lineEditName->text();

# 2.2.11 定时器 QTimer

1
2
3
4
5
6
7
8
#include <QTimer>        //定时器
QTimer *t = new QTimer; //定时器类
connect(t, &QTimer::timeout, [&](){ //捕获定时器timeout信号
static int x = 0;
pbr_schedule->setValue(x++); //在进度条上显示一个数据
lcd_time->display(x); //在7段数码管上显示一个数据
});
t->start(100); //开启定时器(周期性的产生timeout信号)


# 3. 主窗口

# 3.1 基础窗口部件 QWidget

基础窗口部件主要用于自定义窗
QWidge 堤提供一个基础窗口,窗口并没有任何图形部件。通过指定图形部件的父对象来把图形部件放上基础窗口,或是通过自动布局工具把图形部件放上基础窗口。


# 3.2 主窗口 QMainWindow

QMain Window 类提供了一个典型应用程序的主窗口框架,对于小屏幕设备使用 Q 图形设计器定义标准 Qwidget 模板比使用主窗口类更好一些典型模板包含有菜单栏 QMenuBar, 工具栏 TOolbAr 和状态栏 STatus Bar。

#


# 3.3 菜单

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
QAction *actopen = new QAction("打开");
actopen->setIcon(QIcon(":/img/open.png"));
actopen->setShortcut(QKeySequence("Ctrl+O"));
QMenu *fileMenu = menuBar()->addMenu("&File");
fileMenu->addAction(actnew);
fileMenu->addAction(actopen);
void openfile();

//文件打开
#include <QFileDialog>
connect(actopen, SIGNAL(triggered(bool)), this, SLOT(openfile()));
void MainWindow::openfile()
{
QFileDialog::getOpenFileName();
}


//
QAction *actnew = new QAction("新建");
actnew->setIcon(QIcon(":/img/new.png"));
actnew->setShortcut(QKeySequence("Ctrl+N"));
QAction *actopen = new QAction("打开");
actopen->setIcon(QIcon(":/img/open.png"));
actopen->setShortcut(QKeySequence("Ctrl+O"));
QAction *actsave = new QAction("保存");
actsave->setIcon(QIcon(":/img/save.png"));
actsave->setShortcut(QKeySequence("Ctrl+S"));
QAction *actsaveas = new QAction("另存为");
actsaveas->setIcon(QIcon(":/img/saveas.png"));
actsaveas->setShortcut(QKeySequence("Ctrl+Shift+S"));
// 实现文件菜单
QMenu *fileMenu = menuBar()->addMenu("&File");
fileMenu->addAction(actnew);
fileMenu->addAction(actopen);
fileMenu->addAction(actsave);
fileMenu->addAction(actsaveas);

# 3.4 工具栏

#
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <QToolBar>
#include <QFontComboBox>
// 添加工具栏
QToolBar *filetool = addToolBar("文件");
filetool->addAction(actnew);
filetool->addAction(actopen);
QToolBar *edittool = addToolBar("编辑");
edittool->addAction(actcopy);
edittool->addAction(actpaste);
QToolBar *settool = addToolBar("设置");
QFontComboBox *fc = new QFontComboBox;
settool->addWidget(fc);
connect(actopen, SIGNAL(triggered(bool)), this, SLOT(openfile()));

# 3.5 状态栏

  • 中央部件:
    1
    2
    3
    4
    5
    6
    7
    #include <QTextEdit>
    // 添加中央部件
    te = new QTextEdit;
    te->setMinimumSize(640, 480);
    this->setCentralWidget(te);

    connect(actopen, SIGNAL(triggered(bool)), this, SLOT(openfile()));
  • 状态栏
    1
    2
    3
    4
    5
    #include <QLabel>
    // 添加状态栏
    QLabel *lb = new QLabel("1.txt");
    this->statusBar()->addWidget(lb);
    connect(actopen, SIGNAL(triggered(bool)), this, SLOT(openfile()));
  • 操作文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <QFile>
    void openfile();
    void MainWindow::openfile()
    {
    QString filename = QFileDialog::getOpenFileName();
    QFile f(filename);
    f.open(QIODevice::ReadOnly);
    QByteArray buf = f.readAll();
    f.close();
    te->setText(buf);
    }

# 4. 事件和图形系统

# 4.1 事件处理

# 4.1.1 处理鼠标事件

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public:
//处理鼠标事件的虚函数---------------------------------
//鼠标点击事件
void mousePressEvent(QMouseEvent *event);
//
#include "QMouseEvent"
//鼠标点击
void Widget::mousePressEvent(QMouseEvent *event)
{
qDebug () << "mouse pos" << event->pos();
qDebug () << "mouse button" << event->button(); //按键,左键1,右键2,中键4
}
//
//处理鼠标事件的虚函数---------------------------------
//鼠标点击事件
void mousePressEvent(QMouseEvent *event);
//鼠标双击
void mouseDoubleClickEvent(QMouseEvent *event);
//鼠标释放
void mouseReleaseEvent(QMouseEvent *event);
//鼠标移动事件
void mouseMoveEvent(QMouseEvent *event);

# 4.1.2 滚轮事件

#
1
2
3
4
5
6
7
8
//滚轮事件-----------------------------------------------
void wheelEvent(QWheelEvent *event);
#include "QWheelEvent"
//滚轮事件-----------------------------------------------
void Widget::wheelEvent(QWheelEvent *event)
{
qDebug () << event->angleDelta();
}

# 4.1.3 键盘事件

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 //键盘事件-----------------------------------------------
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);

#include "QKeyEvent"

//键盘事件-----------------------------------------------
void Widget::keyPressEvent(QKeyEvent *event)
{
qDebug() << event->key();
}
void Widget::keyReleaseEvent(QKeyEvent *event)
{
qDebug() << event->key();
}

# 4.1.4 窗口关闭事件

#
1
2
3
4
5
6
7
//窗口关闭事件
void closeEvent(QCloseEvent *event);

void Widget::closeEvent(QCloseEvent *event)
{
qDebug()<<"xxxxxxxxxxxxxxxxxxx";
}

# 4.2 绘图基础

Qt 的 2D 绘图系统主要是由于三个基本的类构成: QPainter、QPaintEngine、QPaintDevice。

# 4.2.1 绘图事件

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//绘图事件
void paintEvent(QPaintEvent *event);
void Widget::paintEvent(QPaintEvent *event)
{
qDebug()<<"ddddddddddddddddddddd"<<pos<<posend;
}
//画点
#include <QPainter>
QPoint pos;
QPoint posend;
QPainter p(this);
QPen pen;
p.setPen(pen);
p.drawPoint(pos);
//画线
p.drawLine(pos,posend);
//画椭圆
p.drawEllipse(posend, a, b);
//画矩形
p.drawRect(posend.x(), posend.y(), 300, 200);
//画刷子
QBrush brush;
brush.setColor(Qt::red);
brush.setStyle(Qt::DiagCrossPattern);
p.setBrush(brush); //给画家一个刷子
//画照片
p.drawPixmap(posend.x(), posend.y(), 100, 100, QPixmap("C:\\Users\\29507\\Desktop\\car.png"));

# 4.3 坐标系统

# 4.3.1 画家动作

#
1
2
3
4
QPainter p(this);
p.translate(100, 100); //移动画家
p.scale(0.5, 0.5); //缩放作画
p.drawEllipse(QPoint(0, 0), 100, 100); //相对画家的坐标

# 4.3.2 双缓冲绘图

# <!-- 双缓冲绘图是指先在内存创建对象,将图绘制在对象然后在拷贝这个对象到屏幕上,大大缩短了绘图时间 --->
1
2
3
4
5
6
7
8
9
QPainter p2(this);
p2.drawPixmap(0, 0, 640, 480, *pix);
//p2.drawLine(posstart, posend);
p2.drawRect(QRect(posstart, posend));
QPainter p1(pix);
if(!ismoving){
//p1.drawLine(posstart, posend);
p1.drawRect(QRect(posstart, posend));
}

# 5. 文件处理

# 5.1QFile

#
1
2
3
4
5
6
7
8
9
10
11
12
13
//打开文件
bool QFile:: open(OpenMode mode)
bool QFile:: open (FIle fh, OpenMode mode, FileHandleFlags handleFlags = DontCloseHandle);
bool QFile:: open (int fd, OpenMode mode, FileHandleFlags handleFlags = DontCloseHandle);
//关闭文件
void FIle:: close ();
//设置文件名
QFile:: FIle(const AString& name);
QFile: QFile(const Astring name, QObject parent);
void QFile:: setFileName (const String name);
//读写方法
qint64 read(char data, qint64 maxSize);
qint64 write (const char data, qint64 maxSize);

# 5.2 文件的读写

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <QFile>        //头文件

//文本文件的读写操作
//写
void Widget::on_pushButton_2_clicked()
{
QFile file("text.txt"); //构造file对象
file.open(QFile::WriteOnly | QFile::Truncate); //只写方式打开文件,若文件存在则清空

QByteArray data = ui->lineEdit->text().toLatin1(); //类型与char ch[64] 不同:QByteArray长度是动态匹配内容长度
file.write(data); //给文件写内容
file.close(); //关闭文件
}
//读
void Widget::on_pushButton_clicked()
{
QFile file("test.txt");
file.open(QFile::ReadOnly);

QByteArray data = file.readAll();
ui->lineEdit->setText(data);

file.close();
}

# 5.3 文本流

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <QTextStream>  //文本流   只能操作txt文件
/*通过QTextStream文本流操作文本文件*/
void Widget::on_pushButton_6_clicked() //写
{
QFile file("test.txt");
file.open(QFile::WriteOnly | QFile::Truncate);

QTextStream ts(&file);
ts << ui->lineEdit->text();
file.close();
}

void Widget::on_pushButton_5_clicked() //读
{
QFile file("test.txt");
file.open(QFile::ReadOnly);

QString str;

QTextStream ts(&file); //通过file构造ts
ts >> str; //通过ts读取file中的内容

ui->lineEdit->setText(str); //将str的内容在lineEdit中显示
file.close();
}

# 5.4 数据流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <QDataStream>  //数据流   能操作txt文件,也可以操作dat文件,推荐使用数据流
/*通过QDataStream数据流操作文本文件*/
void Widget::on_pushButton_8_clicked()
{
QFile file("test.dat");
file.open(QFile::WriteOnly | QFile::Truncate);

QDataStream ds(&file); //通过file构造ds
ds << ui->spinBox->value(); //将spinbox中的内容写入file中
file.close();
}

void Widget::on_pushButton_7_clicked()
{
QFile file("test.dat");
file.open(QFile::ReadOnly);

int val;
QDataStream ds(&file); //通过file构造ds
ds >> val;

ui->spinBox->setValue(val); //将ds对应文件中的内容写入spinbox中
file.close();
}

#
1
2
3
4
5
6
7
8
说明:
1.QTextStream只能操作文本文件
  QDataStream:既可以操作文本文件,也可以数据流文件
2.QDataStream不要与read/write混合使用
  QDataStream:遵循Qt的标准字节序
  QFile的read/write:遵循的是主机字节序大端序、大端序
3.QDataStream: 自动根据类型匹配文件内容
  QTextStream: 不会根据类型匹配文件内容

# 5.5 临时文件

#
1
2
3
4
5
bool QTemporary File::open();
/*可以安全的创建一个不会重名的临时文件。
可以设置为手工删除,也可以设置自动删除。默认情况下当对象销毁时候,临时文件也会被自动删除。
可以创建本地临时文件。*/
QTemporaryFile QTemporaryFile::createNativeFile(QFile & file);

# 5.6 目录

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <QDir>
#include <QFileDialog>
void Widget::on_pushButton_clicked()
{
/*获取存在的目录的路径名*/
QString dirPath = QFileDialog::getExistingDirectory(this,
"Open Dir",
QDir::currentPath());
if(dirPath.isEmpty())
return;
ui->lineEdit->setText(dirPath);
ui->textEdit->clear(); //清空textEdit
QDir dir(dirPath); //构造目录对象dir
QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files); //获取目录下的所有文件
for(int i=0; i<fileInfoList.size(); i++) //遍历fileninfolist
{
QFileInfo fileInfo = fileInfoList.at(i); //获取第一个文件的信息
ui->textEdit->append(fileInfo.absoluteFilePath()); //获取文件的绝对路径
ui->textEdit->append(QString::number(fileInfo.size())); //获取文件的大小
}
}

# 5.7 文件信息 QFileInfo

#
1
2
3
4
5
6
7
QFileInfo提供了与系统无关的文件信息。
可以得到绝对、相对、标准路径名称或文件名称文件名、扩展名及名称全称
可以得到文件的类型: 目录、符号链接
可以得到文件的权限
可以得到文件的日期
可以得到文件的大小
可以得到文件的隐藏属性

# 5.8 文件检测

#
1
2
3
4
5
6
7
8
9
10
11
/*QFileSystemWatcher:
QFileSystemWatcher提供了文件或目录的变化情况的管理*/
//添加监测路径
bool QFileSystemWatcher:: addPath(const QString path);
QStringList QFileSystemWatcher:: addPaths(const QStringlist paths);
//删除监测路径
bool QFileSystemWatcher:: removePath (const AString& path);
QStringList QFileSystemWatcher:: removePaths(const QStringlist paths);
//文件或目录改变时Qt发出的信号
void directory Changed (const AString path);
void file Changed(const AString& path);

# 6. 线程和同步互斥

# 6.1 线程 QThread

# 一般的,系统存在两种耗时仼务,CPU 密集操作及 I/O 操作。主流的操作系统都引入了线程的概念。在 GUI 编程中,前台界面操作和后台耗时仼务如果在一个线程中,将使得 GU 面响应缓慢,类似于卡死现象。
Qt 中管理线程的是 QThread:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class My Thread: public QThread
{
Q_OBJECT
...
protected:
void run();
...
};
void MyThread::run(){ ... }
//线程函数(重写虚函数)
void QThread:: run ()
//启动线程
void QThread::start(Priority priority = InheritPriority)
//线程优先级
enum Priority{IdlePriority, LowestPriority, LowPriority, NormalPriority , ... , InheritPriority}
//退出线程
void QThread::exit(int returnCode=0)
//杀死线程
void QThread::terminate()
//设置线程栈
void QThread::setStackSize (uint stackSize)
//等待线程
bool QThread::wait(unsigned long time = ULONG_MAX)
//休眠
void msleep(unsigned long msecs)
void sleep (unsigned long secs)
void usleep(unsigned long usecs)
//事件处理循环
int QThread::exec;

# 6.2 线程同步互斥

竞态:多个执行序列竞争同一个资源就是竞态,譬如:两个进程同时读写同一个文件;两个进程同时读写同一个设备;两个线程同时操作一个全局数据;等等.
竞态产生的原因:

  1. 并发
    主流操作系统都支持多进程、多线程,多个进程、多个线程在并行运行.
  2. 抢占
    当一个执行序列正在运行时,被别执行序列打断,就是抢占。譬如:中断、信号、定时器,等等.

阻止竞态的办法:
设计时候避免使用全局资源
使用同步互斥技术保护全局资源
同步互斥
Qt 关于阻止线程竞态提供了互斥锁、信号量、条件变量等技术
死锁:
所谓死锁就是指多个执行序列为竞争资源而相互等待,并不能正常执行下去的情况
锁粒度
临界区是指在同步互斥技术保护的区域,临界区的范围就是所谓的锁粒度

# 6.2.1 互斥锁

# Qt 提供了互斥锁: QMutex、 QMutexLocker
QMUtex 用于线程间实现互斥操作。
1
2
3
4
5
6
7
8
9
加锁
阻塞版: void QMutex: lock
非阻塞/超时版: bool QMutex: tryLock
解锁
void QMutex:: unlock
锁类型
enum RecursionMode { Recursive, NonRecursive}
判断是否为递归锁
bool QMutex: isRecursive

# 6.2.2 读写锁 QReadWriteLock

# https://www.fearlazy.com/index.php/post/99.html

# 6.2.3 条件变量

#

# 6.2.4 信号量

#

# 7. 进程和进程间通讯

# 7.1 进程

#
1
2
3
4
5
6
7
8
Q提供了 QProcess:创建一个新进程
创建新进程
void QProcess:: start();
int QProcess:: execute ();
bool QProcess:: startDetached ();
杀死当前进程
void QProcess:: kill();
void QProcess:: terminate ();

# 7.2Qt 网络编程

#
1
2
3
4
5
6
7
8
9
10
//Qt提供了基于TCP/P的套接字编程,引用头文件:
#include <QtNetwork>
//Qt的网络模块,在项目文件中添加:
QT += network
//套接字类:
流式: QTcpSocket
数据报: QUdpSocket
//TCP服务器: QTcpServer。
//使用应用层通用协议进行网络操作:
QNetworkRequest, QNetworkReply, QNetworkAccess Manager.

<!-- 这段没学,先学网络再理解 -->

# 8. 补充

# 8.1 应用程序图标

  1. 方法一:
    将 filename.ico 文件放到路径下,在项目文件中加上 RC_ICONS=filename.ico
  2. 方法二:
    项目路径下新建 filename.txt 文件,文件内容:IDI_ICON1 ICON DISCARDABLE "filename.ico"
    重命名为 filename.rc 文件
    项目文件中加上 RC_FILE=filename.rc

# 8.2QSS 美化

<!-- UI 可以直接改,代码需要学一下 -->

# QSS 基础


# 8.3 应用程序打包

步骤:

  1. 复制 name.exe 文件进文件夹
  2. 复制当前路径
  3. 打开 QT 命令行进入文件夹路径
  4. 输入 windeployqt.exe name.exe

多文件打包成一个可执行文件
利用 Enigma Virtual Box 实现
步骤:

  1. 打开.exe 文件
  2. 添加项目文件夹
  3. 执行