• 欢迎来到想想君的青玉案!
  • 欢迎来到我的酒馆,伙计!搓炉石的朋友请加我账号DarrenDing#5404,嘎嘎~

Qt中设计可自适应的用户界面(裸写代码篇)

学习Qt5 Darren Ding 390次浏览 0个评论

我们的征程是星辰大海

博主想用Qt做一个类似QQ的聊天软件,可以在同一局域网中和小伙伴们畅所欲言,你懂得 :grin:  。博主给这款软件起了一个骚气的名字,叫iBBChat。官方翻译为“爱逼逼”。当然,你可以选择称呼它BB(与QQ对应),或BBC(据说,这是博主的一个好友的诨号)。

目标很宏大,博主好激动!千里之行,始于足下。很明显,第一步要设计用户界面(UI)。博主稍微构思了个草图,如下图1。其中,用户可以输入文字,改变字体和格式,然后发送给小伙伴。是不是类似一个富文本编辑器(Rich Text Editor)呢?

分析下整个界面,从上至下可概括为:1-文本预览区;2-字体格式区;3-用户输入区;4-发送按钮区。用Qt组件实现的话,区域1是一个QTextBrower,区域2有一个QFontComboBox,一个QComboBox和四个QToolButton,区域3是一个QTextEdit,区域4是一个QPushButton(备注:其实按钮左侧还有一个水平的空白占位符,程序运行时不会被显示!)。

OK,一切就绪。博主已经等不及了,开始编码吧。

AdaptiveRichEditor

图1 用户界面最终效果草图

九层之台,起于“搬砖”

这一部分,我们使C++代码,一行行地创建Qt界面布局。这确实是件浩瀚的工程。不过,让暴风雨来得更猛烈些吧!

创建一个Qt Widgets Application,在向导对话框中类信息页面,基类选为QWidget,勾掉创建界面复选框(不使用Qt的界面文件.ui),最后完成。如下:

WidgetWithoutQtUi

图2 创建不包含界面文件的QWidget工程

分别在Widget的.h头文件和.cpp源文件中添加代码,完成界面布局。

头文件代码如下:

源文件代码如下:

但是,我还有要说的话

上面的代码博主自认为已经很清晰了,我还有什么话可说呢?不过,下面还是要做进一步地分析。

(一).h文件中的QT_BEGIN_NAMESPACE和QT_END_NAMESPACE宏,可以在global.h中查看其定义。其实就是Qt的命名空间,可类比std命名空间理解(using namespace std;)。两个宏中包围的内容,是程序中用到的Qt组件类的前置声明。关于为何要使用类的前置声明,以及各组件变量为何声明为指针形式,可以参考博客:C++中前置声明和头文件包含

另外,博主习惯写一个私有的成员函数 void initializeUi(); ,用来统一完成用户界面的初始化工作,在构造函数中调用。

(二).cpp文件中,我们来分析 initializeUi() 函数。

  • [1]-[4]创建所有用到的Qt组件并设置一些属性值。
  • [2]中将与字体设置有关的组件统一置于一个水平布局管理器(QHboxLayout)中。
  • [2]中为每个QToolButton各设置了一个图标,来自资源文件resources.qrc,如图3。
  • [4]中代码 footerHBLayout->addStretch(); 的作用:在“发送”按钮左侧添加一个水平空白占位符。
  • [5]为AdaptiveWidget创建一个顶级的布局管理器(这里我们使用QGridLayout,即为栅格布局或网格布局。),自上而下地容纳[1]-[4]的四部分组件。
  • [5]中的顶级布局管理器,保证AdaptiveWidget组件在尺寸变化时,能够自适应调整内部组件的位置和大小。
  • [5]中代码 mainLayout->setRowStretch(0, 2); mainLayout->setRowStretch(2, 1); 作用是把textBrowser和textEdit行的伸缩比设为2:1。
QtResources

图3 为Qt工程添加资源文件

(三)添加资源文件的正确“姿势”。

  • 工程上右键-“添加新文件”-选择“Qt-Qt Resource File”-填写“名称”(如resources)完成;
  • 在工程中查看“资源”-resources.qrc文件,右键resources.qrc-选择“Open in Editor”;
  • 在打开的资源编辑器中选择“添加”下拉菜单添加“前缀”(例如改为/);
  • 图标文件(.png图片)放在工程下的images文件夹下;
  • 在资源编辑器中选择“添加”下拉菜单添加“文件”,选中images下的图标文件即可;
  • 引用资源文件的路径格式为:/images/icon.png(如果设置的前缀为/prefix,则路径为:/prefix/images/icon.png)。

千呼万唤始出来

至此,我们用Qt组件、C++代码、逐行地裸写出了最终的用户界面,是不是有点儿成就感呢?看看我们的成果吧!

AdaptiveWidgetWithouUi

图4 自适应用户界面设计效果

有好事者说

当我们敲完代码,沉浸在收获的喜悦中时,外号“刺头”的小伙伴“赵日天”表示不服:“这个界面我不中意!设置字体相关的组件调整到文本输入框下面,四个工具按钮调整到字体选择组合框的左边,发送按钮调整到左边。。。不然,我不用你这个软件。”

博主表示心理有万千草泥马在狂奔,“什么破审美观?”。不过为了推广产品,该忍还得忍。改代码呗,于是乎,代码改成这样:

更改之后的用户界面,如图5:

AdaptiveWidgetForCustomer

图5 按照用户要求调整后的用户界面

最后的思考

庆幸得是,这个界面上的组件不是很多。调整了几段代码的顺序,改了些许代码的参数,就搞定了好事者的要求。

不过,博主有些后怕。就是这样一个简单的用户界面,都要写上百行代码!如果需要很多子界面,每个界面上的组件又很多,组件间的布局比较复杂,且不说完成既定布局的繁琐,恐怕调整布局时更加麻烦吧!毕竟,我们的重点不只是UI,还有背后的逻辑。我们总不能把80%的时间浪费在写UI上吧?

对于处女座的博主来说,逐行写UI代码的行为,是不能忍受的!在博主的认知里,MVC(Model-View-Controller)架构的软件才具有美感,软件的UI设计和逻辑设计应该分离。博主觉得,模型是软件的躯干肉体,视图是软件的衣服装饰,控制器才是软件的血液思想。

于是,博主陷入沉思:如何以一种更加优雅地方式设计用户界面?欲知详情,且听下回分解。

喜欢 (5)
[187****3312]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址