本博客是在已经写完的一本笔记上而进行的,所以整理清除,结构清晰,有不懂的朋友可以一起交流呀。

下文为了方便,将(xxx.h)和(xxx.cpp)文件放到了一个代码区,以"空格+换行符+//"为分割线

初始代码(main.cpp)

因为main.cpp代码基本一样,因此在下文中该代码区的代码以此为准,如若修改会做说明

#include "mywidget.h"
#include <QApplication> // 应用程序类
#include <QWidget> // 窗口基类:一个大窗口
/*
QApplication应用程序类
Qt头文件my.h
头文件和类名一样
*/
int main(int argc, char *argv[])
{
// 有且只有一个应用程序类的对象
QApplication a(argc, argv);
// MyWidget继承于QWidget,QWidget是一个窗口基类
// 所以MyWidget也是窗口类
// w就是一个窗口
MyWidget w;
// 窗口创建默认是隐藏的,需要人为显示
w.show();
// 让程序一直执行,等待用户操作
return a.exec();
}

(基础 + 代码)部件部分

小贴士(small tips):指定父类(基类)的两种方式

// .cpp
#include <QPushButton>
// 1. setParent关键字
QPushButton b;
b.setParent(&w);
// 2. 通过构造参数传参
QPushButton b(&w);

小贴士(small tips):定义成员变量的两种方式

#include <QPushButton>
// 1. 普通创建(容易造成内存泄漏)
// .h
private:
QPushButton b;
// .cpp
b.setParent(this); // 指定父类
// 2. 通过指针创建
// .h
private:
QPushButton *b;
// .cpp
b2 = new QPushButton(this); // 指定父类

标准信号和槽

信号:由发出者发出的信息

槽:由接收者接收的信息

// mainwidget.h
#include <QPushButton>
private:
QPushButton b; // 定义一个成员对象
// mainwidget.cpp
#include "mainwidget.h"
#include <QPushButton>
#include <QMainWidget> // 主页面的基类,没有Widget类功能多,但是更精

MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
b.setParent(this);
b.setText("沙雕");
b.move(100, 100);

// 信号与槽举例
connect(&b, &QPushButton::pressed, this, &MainWidget::close);
/*
* &b:信号发出者
* &QPushButton::pressed:处理的信号
* this:信号接收者
* &MainWidget::close:槽函数,信号处理函数
*/

MainWidget::~MainWidget() // 析构函数
{

}
}

自 定义槽

// .h
void mySlot() // 声明槽函数
{

}
// .cpp
connect(&b2, &QPushButton::released, this, &MainWidget::mySlot);
void MainWidget::mySlot()
{
b.setText("123"); // 改变b按钮的显示文本
}

自定义信号

小贴士(small tips):创建两个窗口(A,B)并把他们联系起来+自定义信号

conclusion:当父窗口切换到子窗口的时候,直接切换;当子窗口切换到父窗口的时候,因为子窗口是在父窗口之中,因此子窗口必须先发射一个信号,这个信号是由子窗口按钮发出的。

// 第一步:分别创建两个窗口和两个按钮
// A.h
#include <QPushButton> // 给父窗口创建一个按钮用来切换页面
QPushButton b1;
// B.h
#include <QPushButton> // 给子窗口创建一个按钮用来切换页面
QPushButton b2;

// 第二步:把B作为A的子类
// A.h
#include "B.h" // 把子窗口头文件放到父窗口头文件里面
B b; // 创建一个子窗口的类

// 第三步:当是父类窗口的时候,点击按钮,会切换到子类窗口
// A.h
void change_windows(); // 改变窗口的函数
// A.cpp
#include <QPushButton>
connect(&b1, &QPushButton::release, this, &A::change_windows) // 建立一个槽函数
void B::change_windows()
{
this->hide(); // 父窗口隐藏
b.show(); // 子窗口显示
}

// 第四步:当是子类窗口的时候,点击按钮,会切换到父类窗口
// B.h
signals:
void mySiganl();
public:
void sendslots();
// B.cpp
#include <QPushButton>
connect(&b2, &QPushButton::clicked, this, &B::sendslots); // 自定义信号
void B::sendslots()
{
emit mySignal() // 发出信号
}
// A.h
void dealB(); // 父类中的槽函数
// A.cpp
connect(&b, &B::mySignal, this, A::deals); // b表示的是一个窗口,而不是一个按钮
void A::deals()
{
b.hide(); // 子窗口隐藏
this->show(); // 父窗口显示
}

信号二义性

illusion:当出现两个信号的时候,必须在父类中指定接收哪一个信号,不同的信号是由不同的动作发出来的

小贴士(small tips):信号出现重载

// B.cpp
#include <QPushButton>
connect(&b2, &QPushButton::clicked, this, &B::sendslots); // 自定义信号
void B::sendslots()
{
emit mySignal(250, "浩浩牛啊!")
}
// A.cpp
connect(&b, &B::mySignal, this, A::deals);
void A::deals(int a, Qstring str) // 接收信号的时候也要带上参数
{
b.hide(); // 子窗口隐藏
this->show(); // 父窗口显示
}

信号选择性

// 第一种方法:以函数指针代替信号
void (B::*sendslots1)() == &B::mySignal; // 声明这个信号(函数)是没有参数的
connect(&b, &B::sendslots1, this, A::deals);
void (B::*sendslots2)(int QString) == &B::mySignal; // 声明这个信号(函数)是有参数的
connect(&b, &B::sendslots2, this, A::deals);
void A::deals(int a, Qstring str) // 表明调用的是有参数的信号
{
b.hide(); // 子窗口隐藏
this->show(); // 父窗口显示
}
// 第二种方法:Qt4信号连接(容易出问题)
// Qt4槽函数必须有slots关键字来修饰
// A.h 中所有槽函数的声明都必须加上public slots
public slots:
void deal();
connect(&b, SIGNAL(mysignal()), this, SLOT(deal())); // 不带参数的信号和槽函数
connect(&b, SIGNAL(mysignal(int, QString)), this, SLOT(deal(int, QString))); // 带参数的信号和槽函数

lambda表达式之信号

// .cpp
// 变量传入只可读
#include <QPushButton>
#include <QDebug>
connect(&b, &QPushButton::checked,
[=]() // =以值传递传入外部所有的变量(可读),()表示函数的参数是匿名的
{
qDebug() << "你才是个猪头!";
}
)
// 变量传入只可读可改
#include <QPushButton>
#include <QDebug>
connect(&b, &QPushButton::checked,
[=]() mutable // =以值传递传入外部所有的变量(可读可改),()表示函数的参数是匿名的
{
qDebug() << "你才是个猪头!";
}
)
// 对于信号中有参数的情况
#include <QPushButton>
#include <QDebug>
connect(&b, &QPushButton::checked,
[=](bool isCheck) // bool isCheck指的是传入的参数
{
qDebug() << isCheck;
}
)

坐标系统

{
/*对于父窗口(主窗口,坐标系统相对于屏幕
* 原点:相对于屏幕左上角
* x:往右递增
* y:往下递增
*/
move(100, 100);
/*对于父窗口(主窗口,坐标系统相对于父窗口
* 原点:相对于窗口空白左上角(不包括边框)
* x:往右递增
* y:往下递增
*/
b1 -> resize(100, 100);
//设置按钮大小
}

(基础+代码)控件部分

菜单栏和工具栏

// 基类选择QMainWindow
#include "mainwindow.h"
#include <QMenuBar> // 菜单栏
#include <QMenu>
#include <QAction>
#include <QDebug>
#include <QToolBar> // 添加工具栏
#include <QPushButton> // 按钮
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// 菜单栏
QMenuBar *mBar = menuBar(); // 构造参数构建菜单栏
// 添加菜单
QMenu *pFile = mBar->addMenu("文件"); // 添加小菜单
// 添加菜单项,添加动作
QAction *pNew = pFile->addAction("new"); // 每个小菜单里面的部件
connect(pNew, &QAction::triggered,
[=]()
{
qDebug() << "新建被按下";
}
);
pFile->addSeparator(); // 添加分割线
QAction *pOpen = pFile->addAction("open");

// 工具栏,菜单项的快捷方式
QToolBar *toolbar = addToolBar("toolbar");
// 工具栏添加快捷键
toolbar->addAction(pNew); // pNew表示的是菜单项对应的工具项,并且槽函数也是使用的是菜单项的槽函数

QPushButton *b = new QPushButton(this);
b->setText("^>^");
// 添加小控件
toolbar->addWidget(b); // 把工具项绑定按钮
// 信号处理
connect(b, QPushButton::clicked,
[=]()
{
b->setText("*——*");
}
);

}

MainWindow::~MainWindow() // 析构函数
{

}

状态栏

#include <QStatusBar>       // 状态栏
#include <QLabel> // 标签
...
// 状态栏,左下角的状态
QStatusBar *sbar = statusBar();
QLabel *lable = new QLabel(this);
lable->setText("Normal text file");
// 添加小空间
sbar->addWidget(lable);
// 第二种添加方法,默认从左往右依次添加
sbar->addWidget(new QLabel("2", this));
// 第三种添加方法,默认从右往左依次添加
sbar->addPermanentWidget(new QLabel("2", this));
...

核心控件和浮动窗口

#include <QTextEdit>        // 使用文本编辑区,
#include <QDockWidget> // 浮动窗口
// 核心控件
QTextEdit *Te = new QTextEdit(this); // 也可看做是一个小插件
this->setCentralWidget(Te);
// 浮动窗口
QDockWidget *dock = new QDockWidget(this);
this->addDockWidget(Qt::RightDockWidgetArea, dock); // 第一个参数是浮窗的初始位置

QTextEdit *Te2 = new QTextEdit(this); // 也可看做是一个小插件
dock->setWidget(Te2);

模态和非模态对话框

#include "mainwindow.h"
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QMenuBar *mbar = menuBar();
setMenuBar(mbar);
QMenu *menu = mbar->addMenu("对话框");
QAction *p1 = menu->addAction("模态对话框");
connect(p1, &QAction::triggered,
[=]()
{
QDialog dlg;
dlg.exec() // 等待用户操作
qDebug() << "浩浩牛啊!";
}
);
QAction *p2 = menu->addAction("非模态对话框");
connect(p2, &QAction::triggered,
[=]()
{
QDialog *p = new QDialog;
p->setAttribute(Qt::WA_DeleteOnClose); // 关闭的时候才释放内存
p->show();
}
);
}

MainWindow::~MainWindow()
{

}

标准对话框和文件对话框

#include "mainwindow.h"
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QDialog>
#include <QDebug>
#include <QMessageBox> // 对话框
#include <QFileDialog> // 文件对话框
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QMenuBar *mbar = menuBar();
this->setMenuBar(mbar);
QMenu *menu = mbar->addMenu("对话框");
QAction *p1 = menu->addAction("模态对话框");
connect(p1, &QAction::triggered,
[=]()
{
QDialog dlg;
dlg.exec() // 等待用户操作
qDebug() << "浩浩牛啊!";
}
);
QAction *p2 = menu->addAction("非模态对话框");
connect(p2, &QAction::triggered,
[=]()
{
QDialog *p = new QDialog;
p->setAttribute(Qt::WA_DeleteOnClose); // 关闭的时候才释放内存
p->show();
}
);
QAction *p3 = menu->addAction("关于对话框");
connect(p3, &QAction::triggered,
[=]()
{
QMessageBox::about(this, "about", "content"); // about是对话框的标题,content是内容
}
);
QAction *p4 = menu->addAction("问题对话框");
connect(p4, &QAction::triggered,
[=]()
{
int ret = QMessageBox::question(this,
"question", "content"
QMessageBox::Yes |
QMessageBox::Cancel // 指定类型
); // 默认给ok和no按钮
switch(ret)
{
case QMessageBox::Yes:
QDebug << "i am ok";
break;
case QMessageBox::No:
QDebug << "i am bad";
break;
default:
break;
}
}
);
// 文件对话框
QAction *p5 = menu->addAction("文件对话框");
connect(p5, &QAction::triggered,
[=]()
{
QString path = QFileDialog::getOpenFileName(
this, // 指定父对象
"open", // 显示操作
"../", // 显示路径
"source(*.cpp *.h);;Text(*txt);;all(*.*)" // 指定文件格式
);
QDebug() << path;
}
);
}

MainWindow::~MainWindow()
{

}

(进阶+UI)控件大全

如果要找到对应的控件,只需ui->xxx即可

ui->setupUi(this);

Buttons:按钮类

特点:可以自动生成槽函数(右键,转向槽)

类型

作用

Push Button

按钮

Tool Button

按钮

Radio Button

单选按钮

Check Box

多选按钮

Command Link Button

控制链接按钮

Dialog Button Box

ok、cancel

Containers:容器类

类型

作用

Group Box

放大部件容器

Scroll Area

可滑动

Tool Box

抽屉式容器

Tab Widgets

标签式容器

Stacked Widget

栈容器(可切换页面容器)

Frame

带边框的,布局容器

Widget

不带边框的,布局容器

MDI Area

文档分栏显示

Dock Widget

浮动窗口

QAxWidget

、、、

Input Widgets:输入类

类型

作用

Combo Box

下拉自定义选择框

Font Combo Box

字体选怎框

Line Edit(获取内容—text())

行编辑

Text Edit

文本编辑

Plain Text Edit

空白文本编辑

Spin Box

滑动调整数值(整数)

Double Spin Box

滑动调整数值(小数)

Time Edit

时间编辑器

Date Edit

日期编辑器

Date/Time Edit

时间/日期编辑器

Dial

控制器

Horizontal Scroll Bar

横向滚动条

Vertical Scroll Bar

纵向滚动条

Horizontal Slider

横向滑块

Vertical Slider

纵向滑块

Key Sequence Edit

设置快捷方式

小贴士(small tips):对于Line Edit(行编辑)

// 获取编辑框内容
Qstring text();
// 设置编辑框内容
setText();
// 设置显示间隙
setTextMargins(x, y, z, s) // 四个参数分别为距离左上右下的间距
// 设置显示模式
#include <QLineEdit>
setEchoMode(QLineEdit::Normal) 正常显示
setEchoMode(QLineEdit::NoEcho) 不显示任何内容
setEchoMode(QLineEdit::Password) 密码模式
setEchoMode(QLineEdit::PasswordEchoOnEdit) 编辑时显示字符否则为密码模式

Display Widgets:显示类

类型

作用

类型

作用

Label

设置标签

Horizontal Line

横线

Text Browser

文本显示器

Vertical Line

垂直线

Graphics View

绘图工具

OpenGL Widget

此部分不做讲解

Calendar Widget

日历

QDeclarative View

此部分不做讲解

LCD Number

数码管

QQuickWidget

此部分不做讲解

Progress Bar

进度条

QWebView

此部分不做讲解

小贴士(small tips):对于Label类

#include <QLabel>
// 设置文本内容
ui->labelText->setText("xxxx");

#include <QPixmap>
// 设置图片
ui->labelImage->setPixmap(QPixmap("workspace"));
// 让图片自动适应label大小
ui->labelImage->setScaledContents(true);

// 创建动画
#include <QMovie>
QMovie *myMovie = new QMovie("路径");
// 设置动画
ui->labelImage->setMovie(myMovie);
// 启动动画
myMovie->start();
ui->labelImage->setScaledContents(true);

// 设置html
ui->labelUrl->setText("<h1><a href=\"xxx\">xxx</a></h1>");
ui->labelUrl->setOpenExternalLinks(true);

小贴士(small tips):对于Progress Bar类

ui->progressBar->setMinimum(0);   // 设置最小值
ui->progressBar->setMaximum(0); // 设置最大值
ui->progressBar->setValue(0); // 设置当前值

Spacer:弹簧类

类型

作用

Horizontal Spacer

横向弹簧

Vertical Spacer

纵向弹簧

Layouts:布局类

类型

作用

Vertical Layouts

纵向布局

Horizontal Layouts

横向布局

Grid Layouts

网格布局

Form Layouts

表格布局

自定义控件

把两个cpp文件相连接:【提升为】

Qt样式表

selector { attribute: value; },一般selectior为setStyleSheet()
/* such as
* 1. QLabel{ color: red} 第一种使用基本的颜色单词 默认设置的是字体的颜色
* 2. QLabel{ color: sgb(0, 255, 255)} 第二种使用RGB颜色配色
* 3. background-color:sgb(0, 0, 255) 背景色
* 4. background-image:url() 图片
*/

方箱重合

创建可伸缩样式

// 以按钮为例,对于按钮内的图片边框地带距离border距离要有4个像素点
QPushButton
{
border-width:4px;
border-image:url()
}

伪状态

QPushButton::press
{
border-image:url()
}

伪状态列表

伪状态

描述

伪状态

描述

::checked

button部件被选中

::indeterminate

checkbox或radiobutton被部分选中

::disabled

部件被禁用

::off

部件可以切换,且处于off状态

::enabled

部件被启用

::on

部件可以切换,且处于on状态

::focus

部件获得焦点

::pressed

部件被鼠标按下

::hover

鼠标位于部件上

::unchecked

button部件未被选中

注明:写出来作用不大,主要是要自己会使用

事件

具体可见上一篇博客:
​键盘和鼠标事件监听​​

QT中所有的事件类都继承于QEvent.

#include <QMouseEvent>
void mousePressEvent(QMouseEvent *ev) {}; // 鼠标按下
void mouseReleaseEvent(QMouseEvent *ev) {}; // 鼠标抬起
void mouseMoveEvent(QMouseEvent *ev) {}; // 鼠标移动
void enterEvent(QEvent *e); // 进入窗口区域
void leaveEvent(QEvent *e); // 离开窗口区域
void keyPressEvent(QKeyEvent *e) // 键盘按下事件
ev->button() == ???

事件的接收和忽略

ignore();   // 忽略事件,传递给父组件,不是父类 
accept(); //接收事件

event()函数
控制各个函数的进程

#include <QEvent>
// 第一步:在主类头文件里面建立成员函数bool event(xxx)
// 第二步:定义函数来进行事件分发
// 第三步:代码
switch(e->type())
{
case QEvent::Close:
closeEvent(); // closeEvent此函数要自定义
.... // 如果传入的事件已被识别并且处理,则需要返回true,否则返回false,如果直接return true则可以跳过这个事件
}

事件过滤器:bool eventFitler

// 给控件安装过滤器
ui->label->installEventFilter(this); // this 表示是父对象
ui->label->setMouseTrack(); // 鼠标追踪
if(obj == label)
{
// 判断事件
if(e->type() == QEvent:: MouseMove)
{
ui->label->setTEext("sadf");
return true; // 不要让事件传播
}
}

(进阶+代码)其他工具

绘图

文件操作

网络通信

TCP

UDP

线程