Qt教程5—搭积木
文件:
这个例子显示了如何创建多个窗口部件并用信号和槽把它们连接起来,以及如何处理修改大小。
#include <QApplication>
#include <QFont>
#include <QLCDNumber>
#include <QPushButton>
#include <QSlider>
#include <QVBoxLayout>
#include <QWidget>
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));
QLCDNumber *lcd = new QLCDNumber(2);
lcd->setSegmentStyle(QLCDNumber::Filled);
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 99);
slider->setValue(0);
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
connect(slider, SIGNAL(valueChanged(int)),
lcd, SLOT(display(int)));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(quit);
layout->addWidget(lcd);
layout->addWidget(slider);
setLayout(layout);
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
一行一行地品读
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));
QLCDNumber *lcd = new QLCDNumber(2);
lcd->setSegmentStyle(QLCDNumber::Filled);
lcd是一个QLCDNumber,一个把数字按LCD样式显示的窗口部件。这个实例被设置为显示两个数字。我们设置QLCDNumber::segmentStyle属性为QLCDNumber::Filled使LCD更具可读性。
历史小记:QLCDNumber::segmentStyle曾是为Qt写的第一个窗口部件,这要追溯到QPainter仅仅提供一个原始绘图drawLine()的时候。Tetrix示例的初始版本,使用QLCDNumber来显示分数,也是大概在那个时候写的。
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(0, 99);
slider->setValue(0);
用户可以使用QSlider窗口部件来在一定范围内调节一个整数值。
这里我们创建了一个水平的滑块,设置它的最小值为0,最大值为99,并且初始值为0.
connect(slider, SIGNAL(valueChanged(int)),
lcd, SLOT(display(int)));
这里我们用信号/槽机制把滑块的valueChanged()信号和LCD数字的display()槽连接起来了。
无论什么时候滑块的值发生改变,它会通过发射valueChanged()信号来广播这个新值。因为这个信号已经和LCD数字的display()槽相连接,所以当信号被广播的时候,这个槽就被调用。这两个对象中的任何一个都不知道对方。这就是组件编程的本质。
槽不同于普通C++成员函数的方式,但遵循普通C++成员函数的使用规则。
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(quit);
layout->addWidget(lcd);
layout->addWidget(slider);
setLayout(layout);
MyWidget现在使用一个QVBoxLayout来管理它的子窗口部件的几何。由于这个原因,我们没有必要像在第四章里一样给每个窗口部件来指明坐标。另外,使用一个layout来确保当窗口被改变大小的时候子窗口部件也随之改变大小。然后我们用QBoxLayout::addWidget()给layout加上窗口部件quit,lcd和slider。
函数QWidget::setLayout()将layout安装在MyWidget上。这使得layout成为MyWidget的一个子窗口部件所以我们不需要担心它的删除;父—子关系保证了它将被同MyWidget一起删除。而且,QWidget::setLayout()的调用自动的将layout中的窗口部件设置为“子”使得它们是MyWidget的“子”。因为这个,我们不需要具体的去设置为像quit,lcd和slider窗口部件的“父”。
在Qt中,窗口部件或者是其他窗口部件的“子”(如this),或者它们没有“父”。一个窗口部件可以被增加为layout,在这个layout负责那个窗口部件的几何的情形下,但是这个滑块却不能够像一个“父”一样起作用。取而代之的是,QWidget的构造函数包含一个它父窗口部件的QWidget指针,并且QLayout不继承QWidget。
运行这个程序
LCD数字反应了你对滑块做的一切,并且这个窗口部件很好地处理了重新定义大小事件。注意当窗口被重新定义大小(因为它可以)的时候,LCD数字窗口部件也改变了大小,但是其它的还是和原来一样(因为否则它们看起来会很奇怪)。
练习
试着改变LCD的个数,来添加更多的数字或者改变模式(QLCDNumber::setMode())。你甚至可以添加四个按钮来设置基数
你也可以改变滑块的范围。
或许使用QSpinBox比滑块更好?
试着使应用程序在LCD数值溢出的时候退出。
注:本文由Roli翻译,转载请注明,英文原文见http://doc.trolltech.com/4.4/tutorials-tutorial-t5.html