|
—
本帖被 XChinux 执行加亮操作(2008-08-17)
—
QT4.1白皮书--(2、窗体) 2、窗体
Qt有一系列丰富的窗体用于应用程序界面,在特殊需要时可以灵活、容易的被子类继承使用。
窗体是可以组合在一起创建用户界面的可视化元素。按钮、菜单、滚动条、信息对话框以及应用程序窗口都是窗体的具体实例。Qt的窗口不是分成两种“控制”与“窗口”类型,而是任何一种Qt窗口都可以作为控制或容器使用。自己定义窗口可以通过子类化现有的Qt窗体或者自己根据自己定义实现。
标准备的窗体都是通过QWidget类或者它的子类来实现,自定义窗体都可以通过继承标准窗体与重写虚拟函数实现。
一个窗体可能包含许多子窗体,子窗体显示在父窗体的区域内。一个窗体如果没有父窗体即为顶层窗体("窗口"),显示在操作系统桌面的任务栏上。Qt对的窗体的使用没有任何的限制。一些窗体可以成为顶层窗体,或成为别的窗体的子窗体。一个子窗体在其父窗口中的位置,可以通过布局器或者自己需要放置。如是一个父窗体被禁止使用、隐藏、删除,子窗体将相应的产生同样的效果。
标签、消息对话框、提示条及其它显示文字的窗体并不仅仅只能使用单一的颜色、字体、语言。Qt的文本表现窗体,可以显示多语言超文本内容。
2.1、内置窗体
以下屏幕截图展示了应用不同Qt组件的窗体。这些窗体都是用Qt设计器设计具,采用塑料风格,以展示在Qt4在linux下的显示效果
这些窗体包含标准的输入窗体部件,如单行文本输入的QLineEdit,复选框QCheckBox,数值选择QSpinBox与QSlider,单选框QRadioButton,组合框QComboBox,以及复选按钮QPushButton.
同时也展示了容器类窗体QTabWidget与QGroupBox,这种窗体在Qt设计器中可以快速的帮助设计人员设计可维护的窗体。更复杂的窗体如显示在“Create Poster”对话框中的“QScrollArea”,用于显示动态的内容,因此开发人员的使用比设计人员的使用要多。
Qt的窗体比在这展示的要多,许多可用的窗体,在线类文档“Widget Gallery”都有展示。
许多用户界面,可以通过手写代码的方式实现,以下就是对话框“Find Text”中复选框组的实现代码。
QGroupBox *optionsGroupBox = new QGroupBox(tr("Options")); QCheckBox *caseCheckBox = new QCheckBox(tr("C&ase sensitive")); QCheckBox *directCheckBox = new QCheckBox(tr("Search fo&rwards")); QCheckBox *wordsCheckBox = new QCheckBox(tr("Whole &words")); QCheckBox *startCheckBox = new QCheckBox(tr("From &start of text")); QGridLayout *optionsLayout = new QGridLayout; optionsLayout->addWidget(caseCheckBox, 0, 0); optionsLayout->addWidget(wordsCheckBox, 0, 1); optionsLayout->addWidget(directCheckBox, 1, 0); optionsLayout->addWidget(startCheckBox, 1, 1); optionsGroupBox->setLayout(optionsLayout);
2.2自定义窗体
开发人员可能通过继承QWidget或者QWidget的子类定制自己的窗体或对话框。为了展示如何通过继承实现,我们现在将Q4的例子目录下用于显示当前时钟的程序展示如下。
“AnalogClock”窗体在analogclock.h中定义:
#include <QWidget> class AnalogClock : public QWidget { Q_OBJECT public: AnalogClock(QWidget *parent = 0); protected: void paintEvent(QPaintEvent *event); };
这个窗体继承于QWidget类,有一个形参为QWidget,父窗口可选的构造函数,paintEvent()方法从父类继承,将在时钟需要更新的时候调用。
AnalogClock类在analogclock.cpp类中实现:
#include <QtGui> #include "analogclock.h" AnalogClock::AnalogClock(QWidget *parent): QWidget(parent) { QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(update())); timer->start(1000); setWindowTitle(tr("Analog Clock"));
resize(200, 200);
}
构造函数创建一个时间,为窗体设置一个标题,同时为窗体设置一个合理的默认大小。时钟每1000毫秒发出一个信号。在开始之前与窗体的Update()方法,通过“信号与槽”机制连接到起来,确保时钟保持更新。
在每次时钟改变时PainEvent()方法都会被调用一次刷新整个窗口。它使用Qt绘图系统绘制一个含有一个时针及分针的时钟。
void AnalogClock::paintEvent(QPaintEvent *) { static const QPoint hourHand[3] = { QPoint(7, 8), QPoint(-7, 8), QPoint(0, -40) }; static const QPoint minuteHand[3] = { QPoint(7, 8), QPoint(-7, 8), QPoint(0, -70) }; QColor hourColor(127, 0, 127); QColor minuteColor(0, 127, 127); int side = qMin(width(), height()); QTime time = QTime::currentTime();
函数开始的部分定义它们的形状及颜色,用当前窗体的长宽最小值作为时钟的大小。
函数剩下部分用于绘制时钟及其正确的指针位置。
QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.translate(width() / 2, height() / 2); painter.scale(side / 200.0, side / 200.0); painter.setPen(Qt::NoPen); painter.setBrush(hourColor); painter.save(); painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0))); painter.drawConvexPolygon(hourHand, 3); painter.restore(); painter.setPen(hourColor); for (int i = 0; i < 12; ++i) { painter.drawLine(88, 0, 96, 0); painter.rotate(30.0); } painter.setPen(Qt::NoPen); painter.setBrush(minuteColor); painter.save(); painter.rotate(6.0 * (time.minute() + time.second() / 60.0)); painter.drawConvexPolygon(minuteHand, 3); painter.restore();
painter.setPen(minuteColor); for (int j = 0; j < 60; ++j) { if ((j % 5) != 0) painter.drawLine(92, 0, 96, 0); painter.rotate(6.0); } }
主函数在这个例了只有很少的几行,创建一个应用程序对像,构造时钟窗体并显示。最后开始应用程序的事件处理循环以处理事件。
#include <QApplication> #include "analogclock.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); AnalogClock clock; clock.show();
}
这个例子程序包含一个顶层的时钟窗体没有子窗体。更复杂的窗体是通过布局管理器将不同的窗体组合起来。
在线参考:
http://doc.trolltech.com/4.1/qwidget.html http://doc.trolltech.com/4.1/examples.html#widget-examples http://doc.trolltech.com/4.1/tutorial.html http://doc.trolltech.com/4.1/gallery.html
|