• QT布局之QGridLayout嵌套QHBoxLayout


    嵌入式系统开发的,往往都是真全栈开发者。从硬件到驱动到操作系统到应用以及功能界面,是哪里需要搞哪里。这不,最近需要开发一个基于QT的界面功能,涉及到控件布局。因为不熟悉,走了一些弯路。这里将相关调试记录下来,方便以后参考。

    多说一点。早些年不喜欢做UI,觉得体现不了水平,后来工作中涉及到相关开发后,发现界面也不是那么容易的。首先逻辑思维是第一关。业务代码不像系统代码那样,经过长时间的沉淀,功能需求都比较清晰。往往是各种需求一个接一个,前面这样设计了,后面又要因为新的功能,打破之前的流程,最终导致面条式的代码,揉在一起。因此,在最开始功能框架的设计时,好的抽象能力就显得特别特别重要,而且也是能力的一大考验。像QT的信号槽机制,Android的Activity组件机制,都是这类的典型代表。

    其次,很多时候,界面不是独立的,往往都要嵌入到现成的框架中。比如QT也罢,Android也罢,早期的MFC也罢,都需要开发者对所依赖的框架有比较好的掌握。这样才能对各种控件的特性和结合有比较好的掌握,才能高效的写出高性能、稳定的界面应用来。笔者之前曾经做过一个Android下的视频会议应用。这个应用,有多个视频窗口,每个视频窗口里又独立的包含多个功能,还包括一些动态参量的刷新,比如音量。另外还嵌入了地图,地图上又可以浮动视频窗。按照Android的标准组件,一个嵌套一个的方法来设计,最终跑起来,发现能明显感觉到切换过程。打开Android自带的优化工具,可以看到分析出来的组件树十分的庞杂。这时候的优化,就看对Android自身界面设计思想的理解程度了。

    回到主题。主要是这样一个需求:提供一个浮动框,里面展示设备状态,并添加几个控制按钮,根据状态实现一些快捷操作。

    最开始考虑使用GridLayout做大的布局。将整体分为多行多列。逻辑上如下图:

     

    完成后,根据布局要求,有几个小的调整地方。就是这几个调整地方,花了不少时间。

    1 状态展示部分是三列的,按钮只有两个,想让按钮平分整个宽度,也就是一个按钮占用一个半列。如下图所示:

     

    可以直接在GridLayout里嵌QHBoxLayout。QHBoxLayout是水平布局框,控件会在布局中一个一个从左到右排列。示例代码如下:

    1. <layout class="QHBoxLayout" name="control">
    2. <property name="leftMargin">
    3. <number>1</number>
    4. </property>
    5. <property name="rightMargin">
    6. <number>1</number>
    7. </property>
    8. <item row="0" column="0" rowspan="2">
    9. <widget class="QPushButton" name="test1">
    10. <property name="text">
    11. <string> 测试1</string>
    12. </property>
    13. </widget>
    14. </item>
    15. <item row="0" column="1" rowspan="2">
    16. <widget class="QPushButton" name="test2">
    17. <property name="text">
    18. <string> 测试2</string>
    19. </property>
    20. </widget>
    21. </item>
    22. </layout>

    其中,我们将colspan=”3”,这样控件水平占据三个控件格宽度(上一级的GridLayout),但实际只布局了两个。

    2 解决了宽度问题后发现按钮相比状态控件,显得过小。这就导致按钮不容易被点击触摸到。于是就衍生一个新需求,即如何调整按钮的高度。

    这就需要借助rowstretch和rowspan两个属性了。第一个是放在上一级,也就是父一级的布局中的,第二个是放在当前子布局中的。

    第一个属性说明了伸缩因子。值越大,对应item(从0开始)控件的可调整范围就越大。第二个是说在行方向上,占据几个单位大小。这里设定为2,结合伸缩因子,就可以把嵌入的按钮缩放到更大的范围。示例代码如下:

    1. <layout class="QGridLayout" name="gridLayout" rowstretch="5,3,3,3,8" columnstretch="1,20,20"></layout>
    2. ...
    3. <item row="4" column="0" colspan="3" rowspan="2">
    4. <layout class="QHBoxLayout" name="control">
    5. <property name="leftMargin">
    6. <number>1</number>
    7. </property>
    8. <property name="rightMargin">
    9. <number>1</number>
    10. </property>
    11. <item row="0" column="0" rowspan="2">
    12. <widget class="QPushButton" name="test1">
    13. <property name="text">
    14. <string> 测试1</string>
    15. </property>
    16. </widget>
    17. </item>
    18. <item row="0" column="1" rowspan="2">
    19. <widget class="QPushButton" name="test2">
    20. <property name="text">
    21. <string> 测试2</string>
    22. </property>
    23. </widget>
    24. </item>
    25. </layout>
    26. </item>
    27. </layout>

    补充一点,控件布局是可用嵌套的,比如QGridLayout可用在某一个子项中嵌套一个新的QGridLayout,这样就可以实现更加复杂的布局。

  • 相关阅读:
    重装系统后打印机状态已暂停如何恢复
    计算机保研推免面试复习大纲(数学+408)
    猿创征文|一名Python学者在CSDN的蜕变
    【MYSQL】表的综合查询
    [机缘参悟-32]:鬼谷子-抵巇[xī]篇-面对危险与问题的五种态度
    【前端】WebWorker 在前端SPA框架的应用
    删除的照片怎么找回?教你5个好方法快速恢复
    C++ Tutorials: C++ Language: Other language features: Preprocessor directives
    关于序列化协议,你需要知道的一些内容(3)
    flink实战--如何基于java-agent技术增强Flink功能
  • 原文地址:https://blog.csdn.net/wwwyue1985/article/details/127947674