标题是非常的哗众取宠了。这里主要是用来记录一些使用 Qt 的小经验。之前在工作中,会有一些关于 Qt 的经验总结,加之平时自己写一些小东西也有使用 Qt ,所以使用起来会有一些经验教训,聚集起来,姑且叫做 Effective Qt 了。随时想到会随时更新内容。(注:这里会有一些代码设计的思路,不存在绝对的正误,只是一种习惯)
parentWidget()
方法获取 QWidget
指针强制转换为父控件指针,调用父对象方法。 在对子控件布局的时候,某些情况下实例化子控件时传递的父指针会被置空,例如对子控件设置一些特殊的窗口标志。
void paintEvent(QPaintEvent* e)
方法中的逻辑要避免出现间接调用 update()
方法。 由于 update()
方法与 repaint()
机制不同,所以当出现上述情况,并不会直接爆栈,迅速发现问题。而是在某些会导致频繁重绘的操作下,程序异常卡顿,但是不涉及重绘的操作,程序又看起来没问题。
static
Qt 类型。 避免 Qt 类型的某些内容比 QCoreApplication
更早的初始化,导致一些数值异常。比如在更早的时机调用 QStyle::dpiscaled()
,导致无法得到正确的系统DPI。connect()
方法的返回值,可以在 debug 时快速的发现自己的槽和信号没有正确的连接。adjustSize()
、updateGeometry()
以及sizeHint()
是处理复杂界面布局变动的利器。 简单来说 adjustSize()
是根据子控件调整自己的大小,updateGeometry()
是根据自己的大小和子控件的大小调整子控件的布局。在处理复杂布局时,还需要配合每一个控件本身的 sizePolicy()
以及布局的 sizeConstraint()
方可显示出Qt动态布局的威力
updateGeometry()
并不是每次调用都一定会生效,有时候你需要 QLayout::invalidate()
来辅助你更新布局。 Qt只会在它觉得需要重新更新的时候才更新(具体的判断可以参考源码,大意是说调过了 setXXXSize()
这种方法以后,Qt才认为需要重新更新)。这个时候你可以选择拿到控件的 QLayout
然后循环对每个布局调用 QLayout::invalidate()
;在比较特殊的情况下你可以选择用 setFixedSize(sizeHint())
这种奇怪的调用代替循环,当然请在你非常熟悉你在做什么的时候才去用这种方式代替循环。
QLayout
来控制控件的位置,而不是套用一个又一个的 QWidget
,因为永远不能预料到产品会把一个页面上的哪两个控件联系在一起,如果这些控件相隔了几个 QWidget
,拿到它们的指针将是一件非常蛋疼的事未完待续……