常用控件
- 一.Lable
- [二.LCD Number](#二.LCD Number)
一.Lable
QLabel 可以⽤来显⽰⽂本和图⽚.

代码⽰例:显⽰不同格式的⽂本

代码⽰例:显⽰图⽚


此时,如果拖动窗⼝⼤⼩,可以看到图⽚并不会随着窗⼝⼤⼩的改变⽽同步变化

为了解决这个问题,可以在Widget中重写resizeEvent函数。当用户把窗口从A拖到B时,就会触发连续的一系列的resizeEvent。
此处的 resizeEvent 函数我们没有⼿动调⽤,但是能在窗⼝⼤⼩变化时被⾃动调⽤.
这个过程就是依赖C++中的多态来实现的.Qt框架内部管理着QWidget对象表⽰咱们的窗⼝.在窗⼝⼤⼩发⽣改变时,Qt就会⾃动调⽤ resizeEvent 函数.
但是由于实际上这个表⽰窗⼝的并⾮是QWidget,⽽是QWidget的⼦类,也就是咱们⾃⼰写的Widget.此时虽然是通过⽗类调⽤函数,但是实际上执⾏的是⼦类的函数(也就是我们重写后的resizeEvent ).此处属于是多态机制的⼀种经典⽤法.通过上述过程,就可以把⾃定义的代码,插⼊到框架内部执⾏.相当于"注册回调函数"。
代码⽰例:⽂本对⻬,⾃动换⾏,缩进,边距
QFrame 是 QLabel 的⽗类.其中 frameShape 属性⽤来设置边框性质.
QFrame::Box :矩形边框
QFrame::Panel :带有可点击区域的⾯板边框
QFrame::WinPanel :Windows⻛格的边框
QFrame::HLine :⽔平线边框
QFrame::VLine :垂直线边框
QFrame::StyledPanel :带有可点击区域的⾯板边框,但样式取决于窗⼝主题


代码⽰例:设置伙伴
Qt 中, QLabel中写的文本,是可以指定"快捷键"此处快捷键的规则功能上要比QPushButton弱很多.是在文本中使用&跟上一个字符来表示快捷键。比如&A=>通过键盘上的 alt + a来触发这个快捷键.&B=>通过键盘上的 alt + b来触发。绑定了伙伴关系之后,通过快捷键就可以选中对应的单选按钮/复选按钮


此处把label中的⽂本设置为"快捷键&A"这样的形式.其中&后⾯跟着的字符,就是快捷键.可以通过alt+A的⽅式来触发该快捷键
但是注意,这⾥的快捷键和 QPushButton 的不同.需要搭配alt和单个字⺟的⽅式才能触发.

二.LCD Number
QLCDNumer 是⼀个专⻔⽤来显⽰数字的控件.类似于"⽼式计算器"的效果.

代码⽰例:倒计时

QTimer 表⽰定时器.通过 start ⽅法启动定时器之后,就会每隔⼀定周期,触发⼀次QTimer::timeout 信号.
使⽤ connect 把 QTimer::timeout 信号和 Widget::updateTime 连接起来,意味着每次触发QTimer::timeout 都会执⾏ Widget::updateTime

-
上述代码如果直接在Widget构造函数中,通过⼀个循环+sleep的⽅式是否可以呢?显然,这个代码是不⾏的.循环会使Widget的构造函数⽆法执⾏完毕,此时界⾯是不能正确构造和显⽰的.
-
上述代码如果是在Widget构造函数中,另起⼀个线程,在新线程中完成循环+sleep是否可以呢?这个代码同样是不⾏的.Qt中规定,任何对于GUI上内容的操作,必须在主线程中完成.像Widget构造函数,以及connect连接的slot函数,都是在主线程中调⽤的.⽽我们⾃⼰创建的线程则不是.当我们⾃⼰的线程中尝试对界⾯元素进⾏修改时,Qt程序往往会直接崩溃.
这样的约定主要是因为GUI中的状态往往是牵⼀发动全⾝的,修改⼀个地⽅,就需要同步的对其他内容进⾏调整.⽐如调整了某个元素的尺⼨,就可能影响到内部的⽂字位置,或者其他元素的位置.这⾥⼀连串的修改,都是需要按照⼀定的顺序来完成的.由于多线程执⾏的顺序⽆法保障,因此Qt从根本上禁⽌了其他线程修改GUI状态,避免后续的⼀系列问题