最近转战qt, 主要用qt designer 进行GUI开发,记录下实战经验~
1.前言
qt 是跨平台C++图形用户界面应用程序开发框架,可以使用的IDE工具有 qt creator 和 vs, 这里我主要使用 Visual Studio 2017 工具进行程序开发与编写。
2. 环境配置
只写关键步骤~~
(1)安装vs2017+ qt5.9
[Visual Studio Community] 免费使用,到期之后注册登录下就可以永久使用,下载地址:https://visualstudio.microsoft.com/zh-hans/free-developer-offers/ 。
安装时,选择工作负载勾选使用c++的桌面开发,并将C++/CLI支持勾选。
若是windows8,将Windows8.1 SDK 和 UCRT SDK勾选;
若是windows10,勾选windows10 SDK 、 Windows8.1 SDK 和 UCRT SDK。
qt 下载地址:https://download.qt.io/archive/qt/
安装过程略
(2)vs2017 配置qt
- 安装完qt 和 vs之后,需要在vs2017中配置下qt
- vs2017 工具–扩展与更新 搜索qt,进行下载与安装Qt VS Tools
- 重新启动VS2017,菜单栏会出现 QT VS Tools
- Qt VS Tools --Qt Version 中配置qt ,D:\app\Qt\Qt5.9.9\5.9.9\msvc2017_64 改成自己安装的路径
3. 项目导入
3.1 QT VS Tools 导入 .pro 文件
QT VS Tools 中导入 QT 文件是导入.pro文件, 是初始化配置文件;如果新增了.ui /.qrc需要在.pro文件中添加,打开.pro文件时才会默认加载;或者直接通过文件打开.vcxproj, 会加载最新配置。
3.2 通过.sln 打开解决方案
VS2017 文件–打开–项目/解决方案 , 打开的是 .sln文件
3.3 打开别人的.sln项目时,一般需要配置
- 右键项目–选择属性
- 常规–Windows SDK版本,选择自己已经安装的sdk版本[10.0.17763.0]
- 常规–平台工具集,选择已经安装的平台工具集[Visual Studio 2017 (v141)]
- Qt Project Settings–Qt Installation, 选择自己安装的[qt2017_64]
- C/C++ --常规,配置相应的附加包含目录(include 和 lib 文件)
- 链接器–常规,配置相应的附加库目录
- 链接器–输入。配置附加依赖项(lib文件)
4.项目目录结构
外部依赖项: 自动加载编程中引入的文件,一般不需要修改;
Form Files: 存放 .ui 文件;
Header Files:存放 .h 文件;
Resource Files: 存放资源文件,最常见的是.png文件,用于ui 设计,添加样式表-自定义背景图片;
Source Files: 存放 .cpp 源文件
4.1 UI 界面设置
项目文件中 Form Files 文件中存放 .ui文件, 可以基于此文件在Qt Designer窗口中进行UI设计
(1) .ui文件打不开或闪退的原因:不能使用原来默认的打开方式,打开方式要选择自己安装的qt designer.exe文件。
(2) 修改了ui 文件, vs工程中没有及时同步,可以先选中ui文件进行编译,编译之后在重新生成解决方案就可以使用最新的ui文件了, 若还是不可以,需要重新打开项目。
5.qt designer 设计常用操作
.ui 文件一旦创建,不要随意修改其名称,否则容易报错
- 创建ui文件
选择Form Files–添加–新建项–Qt–Qt MainWindow Form File/Qt Widget Form File/Qt Dialog Form File 创建对应的窗口文件。其中MainWindow Form File自带 菜单栏,工具栏和状态栏,根据需求进行创建。 - qt designer 常用工具:属性编辑器, 对象查看器,动作编辑器,信号/槽编辑器,资源浏览器;
- 修改窗口名称:属性:windowTitle ;在对象查看器中点击窗口类对象,在属性编辑器中搜索即可找到,可以修改窗口名称;
- MainWindow 窗口改变菜单栏/子菜单顺序,直接拖拽;
- 改变MainWindow 菜单背景颜色:对象查看器中点击菜单menubar,然后去属性编辑器中进行改变样式表(styleSheet):
background-color: rgb(34, 68, 102); //背景颜色
color:rgb(255, 255, 255) //字体颜色 - MainWindow 添加工具栏:直接将动作编辑器拖拽到工具栏即可;对象查看器:QToolBar --属性编辑器:toolButtonStyle 选择ToolButtonTextBesideIcon,可以设计图标和文本一起显示;
- QToolBar 添加资源图像时要建立.qrc文件导入项目中,否则图标容易加载失败;
- layout无法改变样式表,可以先将layout变成Wiget,然后再针对背景\控件添加颜色(改变样式表),
font: 25 10pt “Microsoft YaHei” ; //字体样式
font: Bold; // 字体加粗
color:rgb(144, 187, 255) //颜色 - 控件随窗口大小而变化:一开始布局为栅格布局,充满整个窗口, 在栅格布局中进行各种类型的布局,布局完成时选择 栅格布局,控件便可以随窗口变化而变化;
- 同一窗口显示不同界面: Container–>Tab Widget/Stacked Widget ,修改tab名称:currentTabText
border-width:0;border-style:outset 无边框
font: 25 9pt “Microsoft YaHei UI Light”; - Container–>Scroll area 没有出现滚动条 :scrollArea < scrollAreaWidgetContents; 勾掉widgetResizable
- label 字体加粗(样式表): font-weight: bold
- LineEdit默认设置垂直策略为Fixed, 所以一定其垂直框中一定加弹簧,不然,界面显示间隔控件很大,很难看
- 信号与槽:信号指动作, 槽指函数;
内置控件函数:可以通过qt designer直接调用: Edit–>编辑信号/槽,可以进行控件内置函数建立信号与槽的连接;
自定义槽函数,需要先在主文件.h中定义成员函数,然后在.cpp中实现函数功能,最后connect实现跳转。注:函数名不得与类名重复。
xxx.h中:
private slots:
void test();
};
.cpp中: 需要先引入#include "xxx.h"文件
void XxxWindow::test()
{
GuidWidget* guid = new GuidWidget();
guid -> show(); //展示某个页面
}
//在qt designer中添加信号与槽函数,不可在.c文件中重复添加,否则容易触发两遍
connect(ui->actionGuide, SIGNAL(triggered()), this, SLOT(test()));
6.编程常用语句
- 页面切换:stackedWidget 切换页面:ui->stackedWidget->setCurrentIndex(0);获取第一页;
//绑定按钮进行切换
connect(ui->pushButton, &QPushButton::clicked, [this]() {ui->stackedWidget->setCurrentIndex(1); });
- 按钮置灰不可点击:
ui->pushButton_2->setEnabled(false);
- qt designer Qlabel text 等于lineEdit 值:
ui->label_12->setText(ui->lineEdit_2->text())
- qt designer setText()中文乱码 : QString::fromLocal8Bit
setText(QString::fromLocal8Bit("完成"))
- if 语句相等判断条件,注意乱码影响 :ui->pushButton_5->text() == QString::fromLocal8Bit(“完成”),如果不这么写,乱码对比,等式永不成立。
- lineEdit 值设置为变量(j)+固定值:
QString new_j = QString::number(j) ; //int 转 QString
lineEdit->setText(QString::fromLocal8Bit("站点" )+ new_j); //j 也需要是QString类型
- QMessageBox: 生成消息对话框
QMessageBox::information(this, "Title", QString::fromLocal8Bit("确定删除此项目! "));
- setStretch()方法指定了包含在该布局中的行或列所占据的窗口部件在该行或该列中所被拉伸的比例
horizontalLayout_42->setStretch(0, 1); 代表第1列占比1份;0代表第1列/行,1代表占比
- 输出变量:qDebug() << a
- qt 将内容打印到日志文件:
#include<fstream>
std::ofstream fout("out.log"); //输出到 out.log文件
std::cout.rdbuf(fout.rdbuf()); //初始化
std::cout << "11111111" << std::endl; //输出的内容
- QString之simplified() :函数把一个字符串首尾的空格不可见字符全部清除,字符串中间的空格(包括单个空格、多个空格、‘\t’, ‘\n’, ‘\v’, ‘\f’, ‘\r’, and ’ ')都统一转化成一个空格。
例:
QString a =" a b c d ";
a.simplified(); -->输出 :"a b c d"
- 信号与槽
(1)pushbutton 与 QAction 连接槽函数:
triggered() 与 clicked() 的区别:
clicked():一般指点击、按下,用于Button发射的信号;
triggered():QAction等的触发;
activated():一般指控件被激活(激活原因可以有很多);
toggle(): 用于ChekBox,非开即关;在Qt中,checkable按纽或是图标的槽函数应该用toggled()事件来激活。
动作编辑器触发自定义槽函数:
connect(ui->actionSaveAs, SIGNAL(triggered()), this, SLOT(saveProject()));
按钮触发自定义槽函数
connect(ui->pushButton_5, SIGNAL(clicked()), this, SLOT(setSite()));
按钮触发内置槽函数
connect(ui->pushButton_5, &QPushButton::clicked, [this]() {});
当函数名命名为: on_pushbutton对象名_clicked()时,无需写connect,也可以触发;
- 获取QLineEdit更新后的值
当我们更新了Line Edit控件中的值时,我们希望获取最新的值,可以使用textEdited()信号, 意思是text内容编辑时产生信号。
例如:当修改Line Edit 内容时,我们获取最新值
connect(QLineEdit_test, SIGNAL(textEdited(const QString&)), this, SLOT(test())); //可以获取QLineEdit更新后的值
//自定义槽函数
QString newProject::test() {
value_edit = QLineEdit_test->text(); //QLineEdit 为edit控件对象名称
return value_edit;
}
- 清空horizontalLayout布局内的所有元素
QLayoutItem *child;
while ((child = ui-> horizontalLayout_test->takeAt(0)) != 0) //ui-> horizontalLayout_test 为对应的horizontalLayout
{
//setParent为NULL,防止删除之后界面不消失
if (child->widget())
{
child->widget()->setParent(NULL);
}
delete child;
}
- 删除Tab Widget的某一页 tab
int temp_tabCount = ui->tabWidget_test->count() - 1; //ui->tabWidget_test 为tab控件对象名称,,计算此控件下共有多少Tab页;
for (int i = temp_tabCount; i >= 2; i--) //仅留一页tab
{
qDebug() << " remove tab: " << i;
ui->tabWidget_test->removeTab(i); //删除tab页
}
7. qt 打包成exe 文件发布
qt debug 下的 exe 可以直接运行吗?不能单纯的copy exe文件,需要进一步打包成文件:(有待验证)
(1)将qt release 文件夹下的 .exe文件单独copy到新建文件夹下
(2)打开 Qt5.9.9(MSVC 2015 32-bit ) ,安装qt时自动安装,版本有所不同
(3)Qt5.9.9(MSVC 2015 32-bit ) 切换到新建文件夹目录路径
(4)输入命令 windeployqt 程序名 回车,将所需的库文件copy到exe文件夹下
(5)双击可以运行,可以打包压缩发给其他用户使用