воскресенье, 9 июня 2013 г.

Кодовое управление виджетами

Рассмотрим простое приложение - ввод пользователем своего возраста с использованием одного из трех вариантов ввода:

  1. непосредственно ввода числа;
  2. посредством стрелок (элемент типа QSpinBox), последовательно увеличивающих или уменьшающих значение;
  3. с помощью специального ползунка (слайдера – элемент типа QSlider).



Кроме того, задано верхнее ограничение вводимого возраста, что должно быть корректно отработано слайдером в крайних положениях, а изменение значения любым способом должно синхронизировать его положение.

По терминологии UNIX и Qt, визуальные объекты – элементы графического интерфейса пользователя называются виджетами (widget – window gadget) и являются потомками класса QWidget. Любой из них может стать главным окном или быть использован другим виджетом, выполняющим роль контейнера. 
В представленном ниже примере виджет hbox назначается главным окном, а его отображение обеспечивается вызовом функции hbox->show(). В главном окне (виджете) размещено три подчиненных виджета – объекты spinBox и slider типов QSpinBox и QSlider, а также btn типа QPushButton (кнопка). Для каждого виджета может быть выбрана одна схема размещения подчиненных виджетов (Layout). В частности для hbox используем схему горизонтального выравнивания QHBoxLayout * layout. 
Связывание главного виджета со схемой размещения выполняется вызовом hbox-> setLayout(layout). Подчиненные виджеты будут отображены в порядке их добавления (вызовы layout->addWidget).
Следующие вызовы обеспечат связывание сигналов valueChanged() объектов spinBox, slider таким образом, чтобы изменение любого из них приводило к изменению другого. 

QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));

Связывание сигнала clicked() объекта btn со слотом close() главного окна приведет к тому, что по нажатию на эту кнопку, окно hbox будет закрыто.

QObject::connect(btn, SIGNAL(clicked(bool)), hbox, SLOT(close()));

Итак, переходим к рассмотрению кода данного приложения.
#include <QApplication>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QSlider>
#include <QSpinBox>
#include <QPushButton>
#include <QTextCodec>

#define RUS(str) codec->toUnicode(str)

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //Обеспечиваем перекодировку русских букв
    //из кодировки, в которой написана программа.
    //"Windows-1251" - для Windows, "ROI8-R" - Linux и т.д.
    QTextCodec * codec=QTextCodec::codecForName("Windows-1251");

    //создаем новоем окно
    QWidget *hbox=new QWidget();
    //устанавливаем заголовок окна
    hbox->setWindowTitle(RUS("Введите ваш возраст"));
    //создаем виджеты и указываем их настройки
    QSpinBox *spinBox=new QSpinBox(hbox);
    QSlider *slider=new QSlider(Qt::Horizontal, hbox);
    //ограничиваем возраст 0-130 лет
    spinBox->setRange(0, 130);
    slider->setRange(0, 130);
    //значение по умолчанию 35
    spinBox->setValue(35);
    //создание виджежа btn и установка надписи на кнопке
    QPushButton * btn= new QPushButton(RUS("Завершение"), hbox);
    //******************************************************
    QHBoxLayout *layout=new QHBoxLayout; //выравнивание по горизонтали
    layout->setContentsMargins(10,10,10,10);//устанавливаем внешние границы
    layout->setSpacing(5);//устанавливаем интервал элементов внутри
    hbox->setLayout(layout); //связываем layout с hbox
    //устанавливаем порядок следования элементов
    layout->addWidget(spinBox);
    layout->addWidget(slider);
    layout->addWidget(btn);

    //связываем сигнал изменения spinBox со слотом slider
    QObject::connect(spinBox, SIGNAL(valueChanged(int)),slider, SLOT(setValue(int)));
    //связываем сигнал изменения slider со слотом spinBox
    QObject::connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int)));
    //связываем сигнал нажатия btn со слотом close главного окна
    QObject::connect(btn, SIGNAL(clicked(bool)), hbox, SLOT(close()));
    //показываем окно

    hbox->show();
    return a.exec();
}


Комментариев нет:

Отправить комментарий