后面会制作一个简单的电子表格软件,这里先用Qt designer开发"Go to Cell"功能(跳转到指定的单元格),界面如下: 一、使用Qt Designer设计界面 启动designer $ export PATH=/opt/Qt5.9.8/5.9.8/gcc_64/bin/:$PATH$ designer 拖拉控件,设置属性: - QLabel:objectName="label",text="&Cell Location";- QLineEdit:objectName="lineEdit";- QPushButton:objectName="okButton",enabled=false,text="OK",default=true;- QPushButton:objectName="cancelButton",text="Cancel";- QWidget:objectName="GoToCellDialog",windowTitle="Go to Cell";- Spacer(分隔符):objectName="horizontalSpacer" 这里之所以将QWidget控件的objectName设置为以大写字母开头的"GoToCellDialog",是因为后面编译源码时,xxx.ui界面文件(XML)时会被转换为ui_xxx.h(C++),ui_xxx.h会以"GoToCellDialog"为类名定义一个界面类,类名的首字母应该大写。 得到第一版ui: 设置布局: - 选中lable和lineEdit,Form->Lay Out Horizontally: * layoutName="topLayout"- 选中horizontalSpacer、okButton、cancelButton,Form->Lay Out Horizontally: * layoutName="botLayout"- 选中goToCellDialog,Form->Lay Out Vertically: * layoutName="mainLayout"- 选中goToCellDialog,Form->Adjust Size; 得到第二版ui: 设置Tab键顺序: Edit->Edit Tab Order,进入Tab编辑模式: F3重新进入Edit Widget模式,保存为: 002_gotocell/gotocelldialog.ui。 添加main.cpp: 观察编译过程: $ lsbuild.sh gotocelldialog.ui main.cpp$ qmake -project$ ls002_gotocell.pro build.sh gotocelldialog.ui main.cpp$ cat 002_gotocell.proFORMS += gotocelldialog.ui$ qmake 002_gotocell.pro$ ls002_gotocell.pro build.sh gotocelldialog.ui main.cpp Makefile$ make * /opt/Qt5.9.8/5.9.8/gcc_64/bin/qmake -o Makefile 002_gotocell.pro * /opt/Qt5.9.8/5.9.8/gcc_64/bin/uic gotocelldialog.ui -o ui_gotocelldialog.h * g++ XXX -o main.o main.cpp * g++ XXX -o 002_gotocell main.o XXX- qmake非常智能,能自动检测到xxx.ui文件;- xxx.ui会被添加到pro文件里,并且会在makefile里生成适当的规则来调用uic;- 在执行make时,uic会将xxx.ui(XML文件)转换为ui_xxx.h(C++文件); ui_gotocelldialog.h里有什么? - 我们在Qt Designer里通过可视化界面设计出来的goToCellDialog被Qt很智能地转换为了一个GoToCellDialog类;- Ui::GotoCellDialog类很显然就是Qt为我们抽离出来的专门负责界面显示的类,开发人员可以轻松地享受界面和业务分离的好处。- GoToCellDialog类没有父类,因此在main.cpp使用该对话框时需要给他传递一个QDialog对象,该QDialog对象是GoToCellDialog类里各种控件的父窗口;- GoToCellDialog->setupUi(QWiget *)接收一个QWiget对象,然后在该对象上添加了QLabel/QLineEdit等控件,并设置了控件的属性、布局等,从而构造出一个"Go to Cell" Dialog;- 在setupUi()里new了许多控件对象,但是没有任何地方delete,是因为Qt在删除父对象(QDialog对象)时,会自动删除其内部的所有子控件对象(QLabel/QPushButton等)和子布局对象 二、为控件添加信号槽 3个待实现的功能: - OK按钮触发跳转操作;- Cancel按钮退出对话框;- 限制lineEdit只能接受有效单元格;为了让对话框支持上面3个功能,最常用的方法就是定义一个新类,该新类同时继承Ui::GotoCellDialog(复用ui类的代码)和QDialog(支持信号槽),该新类的命名惯例是:和Ui::GotoCellDialog同名,但是不在命名空间Ui里。 定义GotoCellDialog: gotocelldialog.h - 槽函数on_lineEdit_textChanged()用于响应QlineEdit的lineEdit_textChange()信号; 嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去! 无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。 点击这里找小助理0元领取:加微信领取资料 实现GotoCellDialog: gotocelldialog.cpp - QRegExp是正则表达式;- QRegExpValidator是正则表达式验证器,将this(GoToCellDialog对象)传递给其构造函数,则QRegExpValidator对象会成为GoToCellDialog对象的子对象,当GoToCellDialog对象被删除时,QRegExpValidator对象也会被自动删除;- Qt的父-子对象机制是在QObejct中实现的,父对象会有一个子对象列表,父对象被删除时,会遍历的删除子对象;- 子控件会显示在它的父对象所在的区域中;- 没有父对象的对象,需要明确地使用delete删除;- clicked()是QDialog的自带信号,accept()/reject()是QDialog自带的槽;- setupUi()会自动将符合on_objectName_signalName()的所有槽和objectName对象的signalName()信号连接在一起,相当于自动建立信号槽: * connect(lineEdit, SIGNAL(textChanged(const Qstring &)), this, SLOT(on_lineEdit_textChanged())); * 信号函数的参数个数只要>=槽函数的参数个数就可以绑定在一起; * 同一组信号槽是可以被重复绑定的,当一个信号发生时,重复绑定的槽会被调用多次。所以当Qt已经帮我们自动绑定信号槽时,就不要再自己手动去绑定了。 * 为了提升代码的可读性,可以不使用on_objectName_signalName()这种槽命名,然后自己去绑定; 修改main.cpp,创建GotoCellDialog对象: 运行效果: 最后,总结一下使用Qt Designer 创建对话框的5个步骤: - 添加控件、设置控件属性;- 设置布局;- 设置Tab键;- 建立信号槽连接;- 实现槽; 使用Qt Designer时,uic会自动为发生变化的窗口重新生成C++代码,开发人员只需对uic生成的类进行子类化,就可以轻松添加自定义函数的功能了,参考: 《C++ GUI Qt4 编程》 文章链接: https://mp.weixin.qq.com/s/arrWq6KOeddd1z7vP_Uxbg 转载自:老吴嵌入式 文章链接: Qt入门_设计GoToCellDialog