Qt适合跨平台开发,但跨平台时如何实现UI布局这种基础只是都鲜有人提及。当然也有可能是太基础,大家觉得没有提及的必要。
但总有学习Qt的新人被这一步难住,笔者愿意来介绍一下Qt平台下,如何同时为多平台布局UI,这里以同时兼容Windows应用和Android应用为例。
我们想要达到的效果很基础也很简单,就是在屏幕中央显示一行文字:
- 在Windows中显示Hello Windows
- 在安卓中显示Hello Android
其中在Windows中,不管窗口大小如何变化, 文字始终保持在窗口中央。
笔者分别用Qt Designer和纯代码实现一次
使用Qt Designer
使用Designer虽然直观,通过拖拽和配置就可以完成布局。但Designer也有一些明显的缺点,比如配置麻烦、相关文档少、不适合多人协作开发等,所以在比较大的开发团队中,少见使用Designer开发的。
想要深入学习Qt开发的朋友,还是要学会使用纯代码完成布局。
这里我们在介绍如何实现上述效果的同时,也为大家展示一下Designer配置麻烦的地方
直接拖放Label
打开mainwindow.ui
,直接从左边拖一个Label
到窗口中:
在Windows中,初始可以保持在中央(毕竟我们放在了中央),但如果改变窗口大小会发现文字是保持不动的。
在安卓中只能看到一点文字
效果如下图:
结合Horizontal Layout + Horizontal Spacer
我们结合Horizontal Layout,先拖入一个Horizontal Layout,再在Layout中增加Label,为了保持Label在屏幕中间,在Label两边各放一个Horizontal Spacer:
在Windows中,初始还是可以保持在屏幕中央,但调整窗口大小时,文字还是保持不动。
在Android中更是直接看不到文字了。
效果如下图:
那么这一步的作用是什么呢?
和直接拖入Label的效果虽然一样,但造成结果的原因不同。前者直接是固定了文字的位置,但后者是因为Horizontal Layout的宽度没有随着窗口大小改变造成的。
为了让Layout能够随着窗口改变大小,在Layout父Widget中点击鼠标右键,选择“布局”->“栅栏布局”
再次运行可以发现,此时不管是在Windows,还是在Android平台,文字可以保持在屏幕中央了。
在Windows平台,改变窗口大小,文字也会随之调整位置,始终保持在屏幕中央。
使用纯代码
利用纯代码实现就相对简单了。
如何改用纯代码方式布局
-
删除
mainwindow.ui
-
编辑
mainwindow.h
和mainwindow.cpp
,删除其中ui相关
-
用代码添加UI布局
#include "mainwindow.h" #include <QHBoxLayout> #include <QLabel> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QWidget *container = new QWidget(); // 创建容器widget this->setCentralWidget(container); // 将容器widget设置为mainwindow的central widget QHBoxLayout *layout = new QHBoxLayout(container); //为容器wiget添加Horizontal Layout QLabel *l = new QLabel("Hello World"); // 新建Label layout->addStretch(); // 在Label左边添加Spacer layout->addWidget(l); //将Label加入Layout中 layout->addStretch(); // 在Label右边添加Spacer } MainWindow::~MainWindow() { }
也可以为container增加一些样式,比如将背景颜色设置为红色:
container->setStyleSheet("background-color:red;");
效果如下:
为不同平台设置不同文字
Qt中有宏可以判断平台:
- Q_OS_WIN:Windows
- Q_OS_MACOS:macOS
- Q_OS_LINUX:Linux
- Q_OS_UNIX:UNIX(包括 Linux、macOS、FreeBSD、OpenBSD 等)
- Q_OS_ANDROID:Android
- Q_OS_IOS:iOS
- Q_OS_WASM:WebAssembly
- Q_OS_DARWIN:Darwin (包括 macOS 和 iOS)
对我们的想要达到的目的,在创建Label时判断平台,创建不同内容的Label:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *container = new QWidget();
container->setStyleSheet("background-color:red;");
this->setCentralWidget(container);
QHBoxLayout *layout = new QHBoxLayout(container);
#if defined(Q_OS_WIN)
QLabel *l = new QLabel("Hello Windows");
#elif defined(Q_OS_ANDROID)
QLabel *l = new QLabel("Hello Android");
#endif
layout->addStretch();
layout->addWidget(l);
layout->addStretch();
}