Qt是一个跨平台的C++图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。
Qt 基础文件
xxx.pro
.pro就是工程文件(project),它是qmake自动生成的用于生产makefile的配置文件
QT += core gui //包含的模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets //大于Qt4版本 才包含widget模块
CONFIG += c++11 //使用c++11的特性
DEFINES += QT_DEPRECATED_WARNINGS
# 工程中包含的文件
SOURCES += \ //源文件
main.cpp \
widget.cpp
HEADERS += \ //头文件
widget.h
FORMS += \ //设计文件
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget> //包含头文件 QWidget 窗口类
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT //Q_OBJECT宏,允许类中使用信号和槽的机制
public:
Widget(QWidget *parent = nullptr); //构造函数
~Widget(); //析构函数
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
//main程序入口 argc命令行变量的数量 argv命令行变量的数组
int main(int argc, char *argv[])
{
QApplication a(argc, argv); //a应用程序对象,在Qt中,应用程序对象 有且仅有一个
Widget w; //窗口对象 Widget父类 -> QWidget
w.show(); //窗口对象 默认不会显示,必须要调用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;
}
信号和槽(Signal & Slot)
信号和槽是 Qt 的核心,它让两个互不相干的对象连接起来,当一个对象的状态改变时,可以通知另一个对象。在Qt中我们需要使用connect函数进二者的关联。
connect(* sender, &signal, * receiver, &slot);
参数解释:
sender:信号发送者
signal:发送的信号(函数地址)
receiver:信号接受者
slot:处理的槽函数(函数地址)
系统自带的信号和槽
例子:点击按钮,关闭窗口
//创建一个按钮
QPushButton * btn = new QPushButton("关闭窗口",this);
//连接信号与槽
connect(btn, &QPushButton::clicked, this, &QWidget::close);
/*
btn -信号发送者(这里是按钮)
&QPushButton::clicked -发送的信号(这里是点击按钮信号)
this -信号接受者(这里是本窗口Widget)
&QWidget::close -信号接收者收到信号干的事(这里是调用的是关闭窗口的函数)
*/
自定义信号和槽
案例–下课后,老师触发饿了信号,学生响应信号,请客吃饭
首先定义一个学生类和老师类:
老师类中声明信号 饿了 hungry
signals:
void hungury();//只需要声明,不需要实现
学生类中声明槽 请客 treat
public slots://早期Qt版本 必须要写到public slots,高级版本可以写到 public或者全局下
void treat();//需要声明,需要实现
在窗口中声明一个公共方法下课,这个方法的调用会触发老师饿了这个信号,而响应槽函数学生请客
void MyWidget::ClassIsOver()
{
//下课函数,调用后,触发老师饿了的信号
emit teacher->hungury();
}
学生响应了槽函数,并且打印信息
//自定义槽函数 实现
void Student::treat()
{
qDebug() << "请老师吃饭!";
}
定义对象
teacher = new Teacher(this);
student = new Student(this);
在窗口中连接信号槽 connect(teacher,&Teacher::hungury,student,&Student::treat);
并且调用下课函数,测试打印出 “请老师吃饭!”
ClassIsOver();
自定义信号和发生重载的解决办法
自定义的信号 hungry带参数,需要提供重载的自定义信号和 自定义槽
void hungury(QString name); 自定义信号
void treat(QString name ); 自定义槽
但是由于有两个重名的自定义信号和自定义的槽,直接连接会报错,所以需要利用函数指针来指向函数地址, 然后在做连接
void (Teacher:: * teacherSingal)(QString) = &Teacher::hungury;
void (Student:: * studentSlot)(QString) = &Student::treat;
connect(teacher,teacherSingal,student,studentSlot);
Lambda 表达式
C++11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。用 Lambda 表达式,我们就不需要在类中对槽函数做任何的声明了。Lambda 表达式是 C++ 11 的内容,在比较低的 Qt版本中,要注意在 Pro 项目文件中加入 CONFIG += C++ 11。
Lambda表达式的基本构成:
[capture](parameters) mutable ->return-type
{
statement
}
//[外部变量访问方式说明符](操作符重载函数参数)mutable ->函数返回值{函数体}
① 外部变量访问方式说明符
[]
,标识一个 Lambda 的开始,这部分必须存在,不能省略。外部变量访问方式说明符只能使用定义 Lambda 为止时 Lambda 所在作用范围内可见的局部变量(包括 Lambda 所在类的 this)。外部变量访问方式说明符有以下形式:
空
。没有使用任何函数对象参数。=
。函数体内可以使用 Lambda 所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。&
。函数体内可以使用 Lambda 所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。this
。函数体内可以使用 Lambda 所在类中的成员变量。a
。将 a 按值进行传递。按值进行传递时,函数体内不能修改传递进来的 a 的拷贝,因为默认情况下函数是const 的。要修改传递进来的 a 的拷贝,可以添加 mutable 修饰符。&a
。将 a 按引用进行传递。a, &b
。将 a 按值进行传递,b 按引用进行传递。=,&a, &b
。除 a 和 b 按引用进行传递外,其他参数都按值进行传递。&, a, b
。除 a 和 b 按值进行传递外,其他参数都按引用进行传递。
② 操作符重载函数参数
标识重载的 () 操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。
③ 可修改标示符
mutable
,这部分可以省略。按值传递函数对象参数时,加上 mutable 修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。
QPushButton * myBtn = new QPushButton (this);
QPushButton * myBtn2 = new QPushButton (this);
myBtn2->move(100,100);
int m = 10;
connect(myBtn,&QPushButton::clicked,this,[m] ()mutable { m = 100 + 10; qDebug() << m; });//m=110
connect(myBtn2,&QPushButton::clicked,this,[=] () { qDebug() << m; });//m=10
qDebug() << m;//m=10
④ 函数返回值
->返回值类型
,标识函数返回值的类型,当返回值为void,或者函数体中只有一处 return 的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。
int ret = []()->int{return 1000}();
qDebug() << "ret=" << ret; //ret=1000
⑤ 函数体
{},标识函数的实现,这部分不能省略,但函数体可以为空。
扩展知识: 按值传递与按引用传递的区别?
按值传递,不会改变当前调用函数里实参,按引用传值,会改变调用里面实参。 按值传递,可以保护实参不被修改,效率比较低。 按引用传值,本质是传递一个指针指向地址值,实参会发生修改,效率更高。
QMainWindow
QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个锚接部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。
菜单栏(QMenuBar)
一个主窗口最多只有一个菜单栏。位于主窗口顶部、主窗口标题栏下面。
//创建菜单 只能一个
QMenuBar * bar = menuBar();
//添加到窗口中
setMenuBar(bar);
//菜单栏
QMenu * fileMenu = bar->addMenu("文件");
QMenu * editMenu = bar->addMenu("编辑");
//菜单项
QAction * newAction = fileMenu->addAction("新建");
//添加分割线
fileMenu->addSeparator();
QAction * openAction = fileMenu->addAction("打开");
工具栏(QToolBar)
主窗口的工具栏上可以有多个工具条,通常采用一个菜单对应一个工具条的的方式,也可根据需要进行工具条的划分。
直接调用QMainWindow类的addToolBar()函数获取主窗口的工具条对象,每增加一个工具条都需要调用一次该函数。
插入属于工具条的动作,即在工具条上添加操作。通过QToolBar类的addAction函数添加。
工具条是一个可移动的窗口,它的停靠区域由QToolBar的allowAreas决定,包括:
Qt::LeftToolBarArea 停靠在左侧
Qt::RightToolBarArea 停靠在右侧
Qt::TopToolBarArea 停靠在顶部
Qt::BottomToolBarArea 停靠在底部
Qt::AllToolBarAreas 以上四个位置都可停靠
使用setAllowedAreas()函数指定停靠区域:
setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea)
- 使用setMoveable()函数设定工具栏的可移动性:
setMoveable(false)
//工具条不可移动, 只能停靠在初始化的位置上
代码承接上面菜单栏部分代码
//创建工具栏 可以多个
QToolBar * toolBar = new QToolBar(this);
//添加到窗口,设置默认停靠区域
addToolBar(Qt::LeftToolBarArea,toolBar);
//设置允许的停靠区域 左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
//设置浮动 不可浮动
toolBar->setFloatable(false);
//设置移动 不可移动
toolBar->setMovable(false);
//工具栏
toolBar->addAction(newAction);
toolBar->addSeparator(); //添加分割线
toolBar->addAction(openAction);
//工具栏添加控件
QPushButton * btn = new QPushButton("按钮",this);
toolBar->addWidget(btn);
状态栏(QStatusBar)
QStatusBar 派生自 QWidget 类,使用方法与 QWidget 类似,状态栏只能有一个。
代码承接上面
//创建状态栏 只能一个
QStatusBar *stBar = statusBar();
//设置到窗口中
setStatusBar(stBar);
//状态栏添加标签控件
QLabel * label = new QLabel("提示信息",this);
stBar->addWidget(label);
QLabel * label2 = new QLabel("右侧提示信息",this);
stBar->addPermanentWidget(label2);
铆接部件(QDockWidget)
铆接部件 QDockWidget,也称浮动窗口,可以有多个。
//浮动窗口 可以多个
QDockWidget * dockWidget = new QDockWidget("浮动窗口",this);
//设置到窗口中
addDockWidget(Qt::BottomDockWidgetArea,dockWidget);
//设置允许的停靠区域 上下停靠
dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
中心部件(CentralWidget)
除了以上几个部件,中心显示的部件都可以作为核心部件,例如一个记事本文件,可以利用QTextEdit做核心部件,中心部件只能有一个。
//设置中心部件 只能一个
QTextEdit * edit =new QTextEdit(this);
setCentralWidget(edit);
资源文件添加
1.将图片文件拷贝到项目位置下
2.右键项目->添加新文件 –> Qt - > Qt recourse File - >给资源文件起名xxx,创建后生成 xxx.qrc
3.右键 xxx.qrc ,选择 open in editor 编辑资源,添加前缀、添加文件
4.使用Qt资源 “ : + 前缀名 + 文件名 ” eg:ui->actionnew->setIcon(QIcon(":/icon/image/jj.ico"));
对话框(QDialog)
对话框分为模态对话框和非模态对话框。模态对话框,会阻塞同一应用程序中其它窗口的输入。非模态对话框,不会阻塞同一应用程序中其它窗口的输入。
模态对话框很常见,比如“打开文件”功能。你可以尝试一下记事本的打开文件,当打开文件对话框出现时,我们是不能对除此对话框之外的窗口部分进行操作的。非模态对话框,例如查找对话框,我们可以在显示着查找对话框的同时,继续对记事本的内容进行编辑。
模态对话框
//模态对话框
connect(ui->actionnew,&QAction::triggered,[=](){
QDialog dlg(this);
dlg.resize(300,100);//设置对话框大小
dlg.setWindowTitle(tr("Hello, Model dialog!"));//设置对话框标题
dlg.setWindowIcon(QIcon(":/icon/image/jj.ico")); //设置对话框图标
dlg.exec();
qDebug() << "模态对话框弹出了";
});
非模态对话框
//非模态对话框
connect(ui->actionnew,&QAction::triggered,[=](){
QDialog * dlg = new QDialog (this); //防止一闪而过,创建到堆区
dlg->resize(300,100); //设置对话框大小
dlg->setWindowTitle(tr("Hello, Modeless dialog!")); //设置对话框标题
dlg->setWindowIcon(QIcon(":/icon/image/jj.ico")); //设置对话框图标
dlg->show();
dlg->setAttribute(Qt::WA_DeleteOnClose); // 55号属性 对话框关闭时,自动销毁对话框。
qDebug() << "非模态对话框弹出了";
});
标准对话框
标准对话框,是 Qt 内置的一系列对话框,用于简化开发。事实上,有很多对话框都是通用的,比如打开文件、设置颜色、打印设置等。这些对话框在所有程序中几乎相同,因此没有必要在每一个程序中都自己实现这么一个对话框。
Qt 的内置对话框大致分为以下几类:
- QColorDialog: 选择颜色;
- QFileDialog: 选择文件或者目录;
- QFontDialog: 选择字体;
- QInputDialog: 允许用户输入一个值,并将其值返回;
- QMessageBox: 模态对话框,用于显示信息、询问问题等;
- QPageSetupDialog: 为打印机提供纸张相关的选项;
- QPrintDialog: 打印机配置;
- QPrintPreviewDialog:打印预览;
- QProgressDialog: 显示操作过程。
消息对话框(QMessageBox)
//消息对话框
connect(ui->actionopen,&QAction::triggered,[=](){
//错误对话框
QMessageBox::critical(this,"错误对话框","错误信息");
//信息对话框
QMessageBox::information(this,"提示对话框","提示信息");
//提问对话框
//参数1:父亲 参数2:标题 参数3:提示内容 参数4:按键类型 参数5:默认关联回车按键
QMessageBox::question(this,"提问对话框","提问信息",QMessageBox::Save|QMessageBox::Cancel);
//警告对话框
QMessageBox::warning(this,"警告对话框","警告信息");
//关于对话框
QMessageBox::about(this,"关于","By 简简");
QMessageBox::aboutQt(this);
});
颜色对话框(QColorDialog)
QColor color = QColorDialog::getColor(QColor(255,0,0));
qDebug() << "r = " << color.red() << " g = " << color.green() << " b = " << color.blue() ;
文件对话框(QFileDialog)
//参数1:父亲 参数2:标题 参数3:默认打开路径 参数4:过滤文件格式
QString str = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\admin\\Desktop","(*.txt)");
qDebug() << str; // 返回值是选取的路径
字体对话框(QFontDialog)
bool flag;
QFont font = QFontDialog::getFont(&flag,QFont("华文彩云",36));
qDebug() << "字体:"<< font.family().toUtf8().data() << "字号:" << font.pointSize() << "是否加粗:" << font.bold() << "是否倾斜:" << font.italic();
常用控件
Buttons
常用按钮(Push Button) QPushButton
工具按钮(Tool Button) QToolButton 用于显示图片,如果想显示文字,修改风格:toolButtonStyle , 凸起风格autoRaise
单选按钮(Radio Button) QRadioButton,设置默认 ui->rBtnMan->setChecked(true);
多选按钮(Check Box) QCheckBox ,监听状态,2 选中 1 半选 0 未选中
//设置单选按钮 男默认选中
ui->rBtnMan->setChecked(true);
//选中女后 打印信息
connect(ui->rBtnWoman,&QRadioButton::clicked,[=](){
qDebug() << "选中了女了!";
});
//多选按钮 2是选中 0是未选中 1是半选
connect(ui->cBox,&QCheckBox::stateChanged,[=](int state){
qDebug() << state;
});
Item Widgets
列表容器(List Widget) QListWidget
QListWidgetItem * item 一行内容
ui->listWidget ->addItem ( item )
设置居中方式item->setTextAlignment(Qt::AlignHCenter);
可以利用addItems一次性添加整个诗内容
//利用listWidget写诗
QListWidgetItem * item = new QListWidgetItem("锄禾日当午");
//将一行诗放入到listWidget控件中
ui->listWidget->addItem(item);
item->setTextAlignment(Qt::AlignHCenter);
树控件(Tree Widget) QTreeWidget
设置头: ui->treeWidget->setHeaderLabels(QStringList()<< “英雄”<< “英雄介绍”);
创建根节点: QTreeWidgetItem * liItem = new QTreeWidgetItem(QStringList()<< “力量”);
添加根节点 到 树控件上:ui->treeWidget->addTopLevelItem(liItem);
添加子节点: liItem->addChild(l1);
//treeWidget树控件使用
//设置水平头
ui->treeWidget->setHeaderLabels(QStringList()<< "英雄"<< "英雄介绍");
QTreeWidgetItem * liItem = new QTreeWidgetItem(QStringList()<< "力量");
QTreeWidgetItem * minItem = new QTreeWidgetItem(QStringList()<< "敏捷");
QTreeWidgetItem * zhiItem = new QTreeWidgetItem(QStringList()<< "智力");
//加载顶层的节点
ui->treeWidget->addTopLevelItem(liItem);
ui->treeWidget->addTopLevelItem(minItem);
ui->treeWidget->addTopLevelItem(zhiItem);
//追加子节点
QStringList heroL1;
heroL1 << "刚被猪" << "前排坦克,能在吸收伤害的同时造成可观的范围输出";
QTreeWidgetItem * l1 = new QTreeWidgetItem(heroL1);
liItem->addChild(l1);
表格控件(Table Widget) QTableWidget
设置列数 :ui->tableWidget->setColumnCount(3);
设置水平表头:ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<”姓名”<< “性别”<< “年龄”);
设置行数:ui->tableWidget->setRowCount(5);
设置正文:ui->tableWidget->setItem(0,0, new QTableWidgetItem(“亚瑟”));
//TableWidget控件
//设置列数
ui->tableWidget->setColumnCount(3);
//设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"姓名"<< "性别"<< "年龄");
//设置行数
ui->tableWidget->setRowCount(5);
//设置正文
//ui->tableWidget->setItem(0,0, new QTableWidgetItem("亚瑟"));
QStringList nameList;
nameList<< "亚瑟"<< "赵云"<< "张飞"<< "关羽" << "花木兰";
QList<QString> sexList;
sexList << "男"<< "男"<< "男"<< "男"<< "女";
for(int i = 0 ; i < 5 ;i ++)
{
int col = 0;
ui->tableWidget->setItem(i,col++, new QTableWidgetItem(nameList[i]));
ui->tableWidget->setItem(i,col++, new QTableWidgetItem(sexList.at(i)));
//int 转 QString
ui->tableWidget->setItem(i,col++, new QTableWidgetItem( QString::number(i+18)));
}
Others
栈控件(Stacked Widget )
ui->stackedWidget->setCurrentIndex(1);
下拉框(Combo Box)
ui->comboBox->addItem("奔驰");
标签(Label ) QLabel
//利用QLabel显示图片
ui->lbl_Image->setPixmap(QPixmap(":/Image/butterfly.png"));
//利用QLabel显示 gif动态图片
QMovie * movie = new QMovie(":/Image/mario.gif");
ui->lbl_movie->setMovie(movie);
//播放动图
movie->start();
文件读写(QFile | QTextStream)
Q t当中使用 QFile 类对文件进行读写操作,对文本文件也可以与 QTextStream 一起使用,这样读写操作会更加简便。QFileInfo 可以用来获取文件的信息。QDir 可以用于对文件夹进行操作。
文件读操作
1、使用QFile类
//获取文件路径
//参数1:父亲 参数2:标题 参数3:默认打开路径
QString path = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\admin\\Desktop");
QFile file(path); //path参数就是读取文件的路径
//设置打开方式
file.open(QIODevice::ReadOnly);
//一次读取所有
QByteArray array = file.readAll();
QString str = QString(array);//类型转换
//按行读
while(!file.atEnd())//atEnd()判断是否读到文件尾
{
QByteArray array += file.readLine();
QString str = QString(array);//类型转换
}
//对文件对象进行关闭
file.close();
QFile::open()
函数打开文件时需要传递 QIODevice::OpenModeFlag
枚举类型的参数,决定文件以什么方式打开,QIODevice::OpenModeFlag
类型的主要取值如下:
- QIODevice::ReadOnly:以只读方式打开文件,用于载入文件。
- QIODevice::WriteOnly:以只写方式打开文件,用于保存文件。
- QIODevice::ReadWrite:以读写方式打开。
- QIODevice::Append: 以添加模式打开,新写入文件的数据添加到文件尾部。
- QIODevice::Truncate: 以截取方式打开文件,文件原有的内容全部被删除。
- QIODevice::Text: 以文本方式打开文件,读取时“\n”被自动翻译为换行符,写入时字符串结束符会自动翻译为系统平台的编码,如 Windows 平台下是“\r\n”。
这些取值可以组合,例如 QIODevice::ReadOnly | QIODevice::Text
表示以只读和文本方式打开文件。
Qt默认使用utf-8的编码方式,在Linux中一般没有问题,因为Linux默认也是用utf-8。不过Windows里一般用的是gb18030,所以除非我们明确将文件保存成utf-8编码,否则在Qt代码里需要对编码做一些转换操作:
QString path = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\admin\\Desktop");
QFile file(path);
file.open(QIODevice::ReadOnly);
QByteArray array = file.readAll();
QTextCodec * codec = QTextCodec::codecForName("gb18030");
QString str = codec->toUnicode(array);//类型转换
file.close();
2、使用QTextStream类
QString path = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\admin\\Desktop");
QFile file(path);
file.open(QIODevice::ReadOnly);
QTextStream in(&file)
while(!in.atEnd())
{
QString str += in.readLine();
}
file.close();
文件写操作
1、使用QFile类
file.open(QIODevice::Append); //用追加方式进行写
file.write("测试");
file.close();
2、使用QTextStream类
file.open(QIODevice::Append); //用追加方式进行写
QTextStream out(&file)
QString str = "测试";
out << str;
file.close();
文件信息读取(QFileInfo)
使用 QFileInfo 获取文件的有关信息。QFileInfo 有很多类型的函数。比如:
size() 文件大小;
fileName() 文件路径;
created() 创建日期;
lastModified() 最后修改日期;
isDir() 检查该文件是否是目录;
isExecutable() 检查该文件是否是可执行文件等。
baseName() 可以直接获得文件名;
completeBaseName() 获取完整的文件名
suffix() 则直接获取文件后缀名。
completeSuffix() 获取完整的文件后缀
//QFileInfo 文件信息类
QFileInfo info(path);
qDebug() << "大小:" << info.size() << " 后缀名:" << info.suffix() << " 文件名称:"<<info.fileName() << " 文件路径:"<< info.filePath();
qDebug() << "创建日期:" << info.created().toString("yyyy/MM/dd hh:mm:ss");
qDebug() << "最后修改日期:"<<info.lastModified().toString("yyyy-MM-dd hh:mm:ss");
});
编码转换
QString -> QByteArray QString.toUtf8();
QByteArray->QString QString(QByteArray)
QByteArray -> std::string QByteArray.toStdString();
std::string -> char * string.data();
Qt资源
Qt Material Design Desktop Widgets :基于Qt Widgets的Material风格控件库
qskinny:Qt 场景图顶部的轻量级框架
QssStylesheetEditor : 一个功能强大的 Qt 样式表(QSS)编辑器,支持实时预览,自动提示,自定义变量, 支持预览自定义ui代码,引用QPalette等功能。
Qt-ShowyWidgets :个人开发的各种花里胡哨的Qt控件集合
赞助💰
如果你觉得对你有帮助,你可以请我喝一杯冰可乐!嘻嘻🤭
支付宝支付 | 微信支付 |