Section 1 Laying Out Widgets on a Form
Qt提供的的基本的Layout Manager包括:QHBoxLayout,QVBoxLayout,QGridLayout和QStackLayout。
Qt中其它能完成Layout management功能的类包括 QSplitter,QScrollArea,QMainWindow和QWorkspace。
Qt中管理child widget的layout共有三种方式:absolute positioning, manual layout和layout managers。
Absolute positioning:即由程序员通过hard-coded的形式管理child widget的位置和尺寸。
Manual Layout:child widget的位置依然由程序员通过hard-coded的方式确定,而尺寸与父窗口的大小成一定比例,而不是完全的hard-coded。这种方式通过对form的resizeEvent()进行再实现来对child widget的定位。
最重要的三个Layout Manger是QHBoxLayout,QVBoxLayout,QGridLayOut,他们都是派生自QLayout
QGridLayout的使用略微有些复杂,它工作在一个由Cell组成的二维grid上。对于QGridLayout,为其添加widget的方式如下:
layout->addWidget(widget,row ,colum,rowSpan,columnSpan)
其中widget为待添加的child widget, row和clomun确定该widget所占据空间中左上角那个Cell的位置坐标,rowSpan和columnSpan则指定widget的大小,这两个参数的的缺省值为1。
addStretch()向Layout Manager中添加“占位符”。
每个widget都有自己的size policy,由其告知layout 系统如何处理该widget外形上的stretch或是shrink。Qt中widget的size policy是通过QSizePolicy类来表示的。每个QSizePolicy由水平和竖直两组size policy组成,最常见的值包括:
Fixed Minimum Maximum Prefered Expanding
除了上述两组size policy外,QSizePolicy中还存储水平和竖直方向的stretch factor,该值用来表明在form尺寸扩展时widget随之扩展的比率。
Section 2 Stacked Layouts
QStackLayout 类可以管理多个page,但每次只显示其中之一,而将其他page向用户隐藏。
QStackLayout类本身是不可见的。
为了方便起见,Qt中包含有QStackedWidget类,即一个内置了QStackedLayout的QWidget。
Section 3 Splitter
类QSplitter是一个能包含其他widget的widget。QSplitter中包含的widget按顺序排列,并被splitter handle相互分隔开。
QSplitter通过构造函数中的参数来来决定是水平方向还是竖直方向。
不同于前面介绍的Layout Mangener们只是负责处理widget的layout而没有可视化的表示,QSplitter派生自QWidget,因此可以同其它widget一样的被使用。
QSplitter类提供了存储自身状态的两个函数:savestate()和restorestate()。
Section 4 Scrolling Areas
QScrollArea类提供了1个可滑动的viewport和2个滑动条。
QScrollArea的使用方法是调用其提供的setWidget()函数,将希望为其添加滑动条的widget添加。QScrollArea自动讲添加进来的widget的parent设定为其viewport,而其viewpoint可通过QScrollArea::viewport()进行访问。
QScrollArea的多数功能是通过继承QAbstraceScrollArea类而获得的。而诸如QTextEdit和QAbstractIterView这样的类是派生自QAbstractScrollArea的,因此不需要将其用QScrollArea类包裹起来以获得scroll bar。
Section 5 Dock Widgets and Toolbars
在Qt中,dock widget是通过QDockWidget类来实现的。
每个dock widget都有自己的title bar。
从Qt4开始,toolbar拥有自己专属的显示空间,而不再是如之前的版本中允许dock widget与其分享。
对一个widget调用setAllowedArea()可以指定允许在那些dock areas上放置该widget。
Section 6 Multiple Document Interface
Qt中,编写MDI程序是通过使用QWorkspace类,将其作为程序的central widget,并把每个文档窗口都作为QWorkspace的child。
Qt程序的命令行参数中与Qt相关的参数,会由QApplication的构造函数负责自动移除掉。
Chapter 7 Event Processing
Qt中大多数event都是作为对用户操作的响应而产生的,但也有一些是系统独立生成的。
在使用Qt进行编程时,通常很少需要考虑event,因为Qt中的widget会在有重要时间发生时emit signal。Event在我们要编写自定义widget或是要修改现有Qt widget的特性时,则变得很重要。
不要在概念上将event和signal两个概念混淆。当(程序员)操纵使用widget时,signal是需要关注的对象;而当(程序员)需要实现一个widget时,event则是需要关注的对象。
例如,当使用QPushButton时,我们更关注其提供的clicked() signal 而不是导致该signal被QPushButton emit的低层次的鼠标或键盘event。但是如果我们要自己实现一个类似于QPushButton的类,那就轮到我们编写代码来处理鼠标和键盘操作,并在必要时emit clicked() signal。
Section 1 Reimplementing Event Handles
Qt中,每个event都是一个派生自QEvent()的对象。Qt中包含超过100种的event,每种event有一个enum value进行标识。
QEvent::type()返回event type。
所有event都是通过其对应类中的event()函数,来向对象发送通告的;这个event()函数继承自QObject。QWidget中event()的实现是将最常见类型的event转发给对应的event handlers,例如mousePressEvent(),keyPress-Event,painEvent()。
键盘event对应的event handler是keyPressEvent()和keyReleaseEvent()。
QKeyEvent::modifiers()
Tab键和Shift+Tab键的处理有些特殊,它们不是由keyPressEvent()负责处理,而是在QWidget::event()中进行处理,而且发生在调用keyPressEvent()之前,处理方式是将输入焦点按照链中的顺序向后或向前传递。
实现key binding的更高层次的实现方式是利用QAction。
QAction类内部使用了QShortCut类来实现key binding。
QObject::startTimer() 用于创建定时器,并返回相应的ID。QObject支持多个定时器同时存在。
killTimer()用于撤销定时器,参数为定时器的ID。
Timer event位于底层,实现定时功能更简单的方式是使用QTimer类,QTimer会定期的emit timeout() siganl。
Section 2 Installing Event Filter
Qt的evnet model中很强大的一个特性,就是可以设定某个对象来监控另外一个对象,后者所有的event在对其可见前都要先通过前一个对象的监控和处理。
Qt中设置event filter涉及到两步操作:
1. 在每个要被监控的对象中调用installEventFilter() 来完成对监控者的注册。
2 在监控者的eventFilter() 中对被监控者的event进行处理。
Qt的event model中,一个event若未得到处理(event handler的返回值为false),则Qt会负责将该event向上传递,即交由其parent负责处理
Qt中对event的处理可以分为下面5个层次
1.对某个特定的event handler进行重实现。
2.对Widget中的QObject::event()进行重实现,这样在event被传递给特定的event handler之前就得到了处理。
3. 为某个对象安装event filter
4. 为QApplication object安装filter,这样可以监控应用程序中所有对象收到的所有event,在进行debug是非常有用。
5. 派生QAapplication的子类,并对notify()进行重实现。Qt调用notify()来发送event的。这是捕获所有event的唯一方法。
Section 3 Staying Responsive During Intensive Processing
在完成耗时操作的同时,还要保证程序能够对用户操作正常相应,常见的解决机制是多线程。
Qt中一种简单的解决方案是在耗时操作的过程中频繁的调用QApplication::processEvnets()。该函数通知Qt处理pending events,处理结束后再将控制权返回至调用者。
Qt中的进度对话框是由QProgressDialog类来实现的。
除了使用多线程和进度对话框外,还存在一种完全不同的处理耗时操作的方法:操作只在程序空闲(无用户交互)时再进行,而不是立刻开始执行。
这种方法可以利用0-milisecond timer来实现,每次定时器触发时,检查是否有pending event,若无则继续好事操作,若有则处理event,完成与用户的交互。
Qt提供的的基本的Layout Manager包括:QHBoxLayout,QVBoxLayout,QGridLayout和QStackLayout。
Qt中其它能完成Layout management功能的类包括 QSplitter,QScrollArea,QMainWindow和QWorkspace。
Qt中管理child widget的layout共有三种方式:absolute positioning, manual layout和layout managers。
Absolute positioning:即由程序员通过hard-coded的形式管理child widget的位置和尺寸。
Manual Layout:child widget的位置依然由程序员通过hard-coded的方式确定,而尺寸与父窗口的大小成一定比例,而不是完全的hard-coded。这种方式通过对form的resizeEvent()进行再实现来对child widget的定位。
最重要的三个Layout Manger是QHBoxLayout,QVBoxLayout,QGridLayOut,他们都是派生自QLayout
QGridLayout的使用略微有些复杂,它工作在一个由Cell组成的二维grid上。对于QGridLayout,为其添加widget的方式如下:
layout->addWidget(widget,row ,colum,rowSpan,columnSpan)
其中widget为待添加的child widget, row和clomun确定该widget所占据空间中左上角那个Cell的位置坐标,rowSpan和columnSpan则指定widget的大小,这两个参数的的缺省值为1。
addStretch()向Layout Manager中添加“占位符”。
每个widget都有自己的size policy,由其告知layout 系统如何处理该widget外形上的stretch或是shrink。Qt中widget的size policy是通过QSizePolicy类来表示的。每个QSizePolicy由水平和竖直两组size policy组成,最常见的值包括:
Fixed Minimum Maximum Prefered Expanding
除了上述两组size policy外,QSizePolicy中还存储水平和竖直方向的stretch factor,该值用来表明在form尺寸扩展时widget随之扩展的比率。
Section 2 Stacked Layouts
QStackLayout 类可以管理多个page,但每次只显示其中之一,而将其他page向用户隐藏。
QStackLayout类本身是不可见的。
为了方便起见,Qt中包含有QStackedWidget类,即一个内置了QStackedLayout的QWidget。
Section 3 Splitter
类QSplitter是一个能包含其他widget的widget。QSplitter中包含的widget按顺序排列,并被splitter handle相互分隔开。
QSplitter通过构造函数中的参数来来决定是水平方向还是竖直方向。
不同于前面介绍的Layout Mangener们只是负责处理widget的layout而没有可视化的表示,QSplitter派生自QWidget,因此可以同其它widget一样的被使用。
QSplitter类提供了存储自身状态的两个函数:savestate()和restorestate()。
Section 4 Scrolling Areas
QScrollArea类提供了1个可滑动的viewport和2个滑动条。
QScrollArea的使用方法是调用其提供的setWidget()函数,将希望为其添加滑动条的widget添加。QScrollArea自动讲添加进来的widget的parent设定为其viewport,而其viewpoint可通过QScrollArea::viewport()进行访问。
QScrollArea的多数功能是通过继承QAbstraceScrollArea类而获得的。而诸如QTextEdit和QAbstractIterView这样的类是派生自QAbstractScrollArea的,因此不需要将其用QScrollArea类包裹起来以获得scroll bar。
Section 5 Dock Widgets and Toolbars
在Qt中,dock widget是通过QDockWidget类来实现的。
每个dock widget都有自己的title bar。
从Qt4开始,toolbar拥有自己专属的显示空间,而不再是如之前的版本中允许dock widget与其分享。
对一个widget调用setAllowedArea()可以指定允许在那些dock areas上放置该widget。
Section 6 Multiple Document Interface
Qt中,编写MDI程序是通过使用QWorkspace类,将其作为程序的central widget,并把每个文档窗口都作为QWorkspace的child。
Qt程序的命令行参数中与Qt相关的参数,会由QApplication的构造函数负责自动移除掉。
Chapter 7 Event Processing
Qt中大多数event都是作为对用户操作的响应而产生的,但也有一些是系统独立生成的。
在使用Qt进行编程时,通常很少需要考虑event,因为Qt中的widget会在有重要时间发生时emit signal。Event在我们要编写自定义widget或是要修改现有Qt widget的特性时,则变得很重要。
不要在概念上将event和signal两个概念混淆。当(程序员)操纵使用widget时,signal是需要关注的对象;而当(程序员)需要实现一个widget时,event则是需要关注的对象。
例如,当使用QPushButton时,我们更关注其提供的clicked() signal 而不是导致该signal被QPushButton emit的低层次的鼠标或键盘event。但是如果我们要自己实现一个类似于QPushButton的类,那就轮到我们编写代码来处理鼠标和键盘操作,并在必要时emit clicked() signal。
Section 1 Reimplementing Event Handles
Qt中,每个event都是一个派生自QEvent()的对象。Qt中包含超过100种的event,每种event有一个enum value进行标识。
QEvent::type()返回event type。
所有event都是通过其对应类中的event()函数,来向对象发送通告的;这个event()函数继承自QObject。QWidget中event()的实现是将最常见类型的event转发给对应的event handlers,例如mousePressEvent(),keyPress-Event,painEvent()。
键盘event对应的event handler是keyPressEvent()和keyReleaseEvent()。
QKeyEvent::modifiers()
Tab键和Shift+Tab键的处理有些特殊,它们不是由keyPressEvent()负责处理,而是在QWidget::event()中进行处理,而且发生在调用keyPressEvent()之前,处理方式是将输入焦点按照链中的顺序向后或向前传递。
实现key binding的更高层次的实现方式是利用QAction。
QAction类内部使用了QShortCut类来实现key binding。
QObject::startTimer() 用于创建定时器,并返回相应的ID。QObject支持多个定时器同时存在。
killTimer()用于撤销定时器,参数为定时器的ID。
Timer event位于底层,实现定时功能更简单的方式是使用QTimer类,QTimer会定期的emit timeout() siganl。
Section 2 Installing Event Filter
Qt的evnet model中很强大的一个特性,就是可以设定某个对象来监控另外一个对象,后者所有的event在对其可见前都要先通过前一个对象的监控和处理。
Qt中设置event filter涉及到两步操作:
1. 在每个要被监控的对象中调用installEventFilter() 来完成对监控者的注册。
2 在监控者的eventFilter() 中对被监控者的event进行处理。
Qt的event model中,一个event若未得到处理(event handler的返回值为false),则Qt会负责将该event向上传递,即交由其parent负责处理
Qt中对event的处理可以分为下面5个层次
1.对某个特定的event handler进行重实现。
2.对Widget中的QObject::event()进行重实现,这样在event被传递给特定的event handler之前就得到了处理。
3. 为某个对象安装event filter
4. 为QApplication object安装filter,这样可以监控应用程序中所有对象收到的所有event,在进行debug是非常有用。
5. 派生QAapplication的子类,并对notify()进行重实现。Qt调用notify()来发送event的。这是捕获所有event的唯一方法。
Section 3 Staying Responsive During Intensive Processing
在完成耗时操作的同时,还要保证程序能够对用户操作正常相应,常见的解决机制是多线程。
Qt中一种简单的解决方案是在耗时操作的过程中频繁的调用QApplication::processEvnets()。该函数通知Qt处理pending events,处理结束后再将控制权返回至调用者。
Qt中的进度对话框是由QProgressDialog类来实现的。
除了使用多线程和进度对话框外,还存在一种完全不同的处理耗时操作的方法:操作只在程序空闲(无用户交互)时再进行,而不是立刻开始执行。
这种方法可以利用0-milisecond timer来实现,每次定时器触发时,检查是否有pending event,若无则继续好事操作,若有则处理event,完成与用户的交互。