Виджеты в фреймворке Qt

Qt является очень популярным фреймворком на C++ для создания оконных приложений и поэтому обделять его вниманием не стоит. Как же он устроен? Он довольно прост и лаконичен. Всё визуальные элементы на форме в Qt являются виджетами (widget). Как же их создавать в программном коде, добавлять на форму и связывать с действиями? Посмотрим на примерах.

Виджеты в Qt являются полностью независимыми элементами, т.е. их можно показывать сразу после создания даже не добавляя на форму (окно) и они сами создадут для себя окно.

Для тренировки писать код виджетов будем прямо в функции main, которая в простом виде в оконном приложении Qt с главным окном выглядит так:

int main(int argc, char *argv[]) {
    QApplication a(argc, argv); // create Qt app
    MainWindow w; // create Qt window
    // there your main code
    w.show(); // show Qt window
    return a.exec(); // execute Qt app
}

В области «there your main code» пишем свой код создания виджетов.

Динамическое (в куче) создание виджета типа label, задание ему текста и показывание:

QLabel *label1 = new QLabel();
label1->setText("some");
label1->show();

Статическое (на стеке) создание виджета типа label, присвоение ему текста (передача строки в конструктор) и отображение:

QLabel lbl("Hello world");
lbl.show();

У каждого виджета есть свой набор действий/событий, которые в Qt называются сигналами в то время как слушатели событий называются слотами. Сигналы и слоты связываются при помощи метода connect класса QObject.

Динамическое создание кнопки, отображение и связывание её сигнала «клик» со слотом (действием) «выход»:

QPushButton *pb = new QPushButton("close");
pb->show();
QObject::connect(pb, SIGNAL(clicked()), &a, SLOT(quit()));

Динамическое создание спинбокса и слайдера:

QSpinBox *sb = new QSpinBox;
QSlider *sl = new QSlider(Qt::Horizontal);

У каждого типа виджета есть свои уникальные свойства помимо общих свойств (размер, положение, etc).

Установка созданным виджетам максимально возможных значений:

sb->setMaximum(100);
sl->setMaximum(100);

Связывание сигнала изменения со слотом в котором устанавливается значение другого элемента:

QObject::connect(sb, SIGNAL(valueChanged(int)), sl, SLOT(setValue(int)));
QObject::connect(sl, SIGNAL(valueChanged(int)), sb, SLOT(setValue(int)));

Так же как и в Java в Qt есть различные слои размещения (лэйауты) для более лёгкого размещения элементов на форме и для их автоматического позиционирования при изменении размеров формы.

Динамическое создание окна и слоя размещения (лэйаута):

QWidget *window = new QWidget;
QHBoxLayout *layout = new QHBoxLayout;

Добавление предыдущих виджетов в созданный лэйаут:

layout->addWidget(sb);
layout->addWidget(sl);

Добавление лэйаута в окно и показ окна:

window->setLayout(layout);
window->show();

Как видно, создавать виджеты, лэйауты и окна (формы) в Qt совсем не сложно.