文件:
这个例子显示了如何把两个窗口部件封装成一个新的组件以及使用多个窗口部件有多容易。首先,我们使用一个自定义窗口部件作为子窗口部件。
#include <QApplication>
#include <QFont>
#include <QGridLayout>
#include <QLCDNumber>
#include <QPushButton>
#include <QSlider>
#include <QVBoxLayout>
#include <QWidget>
class LCDRange : public QWidget
{
public:
LCDRange(QWidget *parent = 0);
};
LCDRange::LCDRange(QWidget *parent)
: QWidget(parent)
{
QLCDNumber *lcd = new QLCDNumber(2);
lcd->setSegmentStyle(QLCDNumber::Filled);
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 99);
slider->setValue(0);
connect(slider, SIGNAL(valueChanged(int)),
lcd, SLOT(display(int)));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(lcd);
layout->addWidget(slider);
setLayout(layout);
}
class MyWidget : public QWidget
{
public:
MyWidget(QWidget *parent = 0);
};
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
QPushButton *quit = new QPushButton(tr("Quit"));
quit->setFont(QFont("Times", 18, QFont::Bold));
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
QGridLayout *grid = new QGridLayout;
for (int row = 0; row < 3; ++row) {
for (int column = 0; column < 3; ++column) {
LCDRange *lcdRange = new LCDRange;
grid->addWidget(lcdRange, row, column);
}
}
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(quit);
layout->addLayout(grid);
setLayout(layout);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
一行一行地品读
LCDRange窗口部件是一个没有任何API的窗口部件。它只有一个构造函数。这种窗口部件不是很有用,所以我们等会将加入一些API。
LCDRange::LCDRange(QWidget *parent)
: QWidget(parent)
{
QLCDNumber *lcd = new QLCDNumber(2);
lcd->setSegmentStyle(QLCDNumber::Filled);
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 99);
slider->setValue(0);
connect(slider, SIGNAL(valueChanged(int)),
lcd, SLOT(display(int)));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(lcd);
layout->addWidget(slider);
setLayout(layout);
}
这是直接从第五章拿过来的MyWidget的构造函数。唯一不同的是Quit按钮被去掉了并且这个类被重命名了。
MyWidget也是除了一个构造函数之外没有任何API。
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
QPushButton *quit = new QPushButton(tr("Quit"));
quit->setFont(QFont("Times", 18, QFont::Bold));
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
过去被放在某个地方的这个按钮现在被放在分开的LCDRange中,这样我们可以拥有一个“Quit”按钮以及许多LCDRange对象。
QGridLayout *grid = new QGridLayout;
我们创建了一个QWidget即一个将包含三列的 QGridLayout。
这个QGridLayout自动地把它的窗口部件排列到行列中;你可以在添加窗口部件给这个layout的时候指定行和列的数量,并且QGridLayout可以将它们安放到网格中。
for (int row = 0; row < 3; ++row) {
for (int column = 0; column < 3; ++column) {
LCDRange *lcdRange = new LCDRange;
grid->addWidget(lcdRange, row, column);
}
}
我们创建了9个LCDRange,所有的这些都是这个grid对象的子窗口部件,并且我们将它们排列成3行3列。
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(quit);
layout->addLayout(grid);
setLayout(layout);
}
最后,我们向主构图中添加“Quit”按钮和包含LCDRange窗口部件的网格构图。QWidget::addLayout()函数和QWidget::addWidget()函数类似,让给定的构图成为主构图的子构图。
完。
运行这个应用程序
这个程序显示了同时使用多个窗口部件有多容易。每一个的行为像滑块和LCD数字已经在前一章提到过了。再提一次,不同在于实现。
练习
在开始的时候用不同的或者随机的值初始化每一个滑块。