• QLayout 删除widget中的子控件,父控件大小不能自适应


    最近遇到一个需求,要是父控件中的子控件是动态的,同时父控件的尺寸要随着自控件的变化而变化。

    源码是这样子做的:

    QLayout删除或增加layoutitem时候,会调用invalidate函数,setDirty为false,把rect置为空。再调用update函数。update函数会判断下当前界面是不是active的,然后发送一个LayoutRequest事件。事件循环器在QApplication的notify_helper中分配这个事件到QLayout。QLayout再调用active函数。active根据QLayout的sizeConstraint模式,

    SetFixedSize, SetMinimumSize,SetMaximumSize,SetMinAndMaxSize,SetDefaultConstraint约束父控件的最大最小尺寸。 QLayout默认是SetDefaultConstraint,

    这个模式下,会通过totalMininumSize()这个函数得到当前的最小尺寸。然后根据Layout的方向,把父控件的最小尺寸设置到size中去。最好把这个尺寸设置到父控件的minimunsize中去。

    接着调用doResize,拿到当前父控件的size,根据是否有menubar,重新计算一遍Geometry。

    最后updateGeometry。

    总之,重点就是layout更新之后只是设置了最小的尺寸,而父控件的更新size的策略会先和最小尺寸比较下。再跟新自己的尺寸。

    也就解释了为什么增加会刷新父控件的尺寸,而减少不会更新父控件的尺寸。

    那么怎么去解决这个问题呢。

    我们就要去分析QWidget的sizeHinit函数。这个函数是通过父控件的totalSizeHint()去获得QLayout的尺寸的。

    在totalSizeHint中,会先或者QLayout的sizeHint的尺寸。然后那个父控件的Margin。把size和margin相加返回。

    分析QLayout的 sizeHint函数发现会判断下当前的Layout是不是dirty的,然后调用setupGeom函数,setupGeom会计算Layout中的各个子控件,的最大值最小值以及默认的size,汇总以后保存。也就是说可以拿到layout的sizeHint尺寸去resize父控件。

    还有一个问题,增加子控件之后,更新layout尺寸会发出一个Layout异步事件,会导致sizihint和miniSize的尺寸跟不及时。需要在处理完事件之后再刷新尺寸。

    所以我们要等到父控件处理完LayoutRequest事件之后再去刷新尺寸。研究Layout源码发现。处理LayoutRequest时候之后,会调用一边setGeometry这个虚函数函数,于是重写这个最后的解决发难就是重写这个虚函数,再setGeometry之后发送一个刷新的信号,刷新主界面。

  • 相关阅读:
    学点设计模式,盘点Spring等源码中与设计模式的那些事之行为型模型
    Lumiprobe Lumizol RNA 提取试剂解决方案
    【2】c++设计模式——>UML表示类之间的继承关系
    QCC51XX---stack大小修改
    react-native开发之flow配置
    突击备战2022秋招,最新Java面试八股文《Java面试真题复盘笔记》来袭,不可错过
    C++new表达式
    干货 | 接口自动化测试分层设计与实践总结
    关于nacos的配置获取失败及服务发现问题的排坑记录
    下一代无线局域网-高吞吐率
  • 原文地址:https://blog.csdn.net/Mario_z/article/details/116310928