Библиотека сайта rus-linux.net
Разработка приложений с использованием Qt, часть 4
Оригинал: Developing Apps on Qt, Part 4Автор: Manoj Kumar
Дата публикации: 3 мая 2012 г.
Перевод: А.Панин
Дата публикации перевода: 8 ноября 2012 г.
В предыдущей статье мы поработали с механизмом сигналов и слотов, являющимся основой Qt при создании графических интерфейсов. В этой статье мы двинемся дальше и рассмотрим часть фреймворка Qt, предназначенную для создания графических интерфейсов.
Виджет является основным строительным блоком графического интерфейса любого приложения и позволяет выполнять такие функции, как создание кнопок, списков, и.т.д. В Qt класс QWidget является базовым классом для всех остальных классов компонентов графического интерфейса. В нем реализованы базовые функции, такие, как прием событий от клавиатуры и мыши.
Одним из самых простых, но очень важных виджетов является кнопка. Например, на Рисунке 1 показано диалоговое окно с двумя кнопками "Cancel" и "Close Tabs", которое отображается при попытке закрытия окна браузера Firefox с несколькими открытыми вкладками. Без кнопок графические интерфейсы становятся бесполезными. Все классы виджетов-кнопок наследуются от класса QAbstractButton, который представляет четыре сигнала - clicked(), pressed(), released() и toggled(), и пять состояний - isChecked(), isEnabled(), isDown(), setCheckable() и setAutoRepeat(). Мы затронем их в примере исходного кода позднее. Некоторые классы, наследуемые от QabstractButton: QPushButton, QRadioButton и QCheckBox.
Рисунок 1: Кнопки PushButton (или просто кнопки)
Давайте начнем рассмотрение виджетов с класса QPushButton. Этот виджет используется для того, чтобы позволить пользователю инициировать какое-либо действие, примерами являются кнопки "OK", "Отмена", "Применить", "Сохранить", и.т.д. Виджет QPushButton генерирует сигналы clicked(), pressed() и released(). Мы будем использовать механизм сигналов и слотов, описанный в предыдущей статье, для демонстрации принципа использования кнопок.
Создайте приложение с графическим интерфейсом ("GUI приложение Qt") и перетащите виджет pushButton на окно диалога. Вы можете изменить имя виджета со стандартного pushButton при помощи клика правой кнопкой мыши, выбора пункта "Изменить objectName" ("Change objectName") во всплывающем меню и ввода нового имени в появившемся окне. Таким же образом вы можете переименовать диалоговое окно и другие классы.
| Примечание: исходный код программ из данной статьи доступен в формате zip-архива по ссылке. |
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog: public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
private slots:
void button_clicked();
void button_pressed();
void button_released();
};
#endif // DIALOG_H
#include "dialog.h"
#include "ui_dialog.h"
#include <QtCore>
Dialog::Dialog(QWidget *parent):
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->clickme, SIGNAL(clicked()), this, SLOT(button_clicked()));
connect(ui->clickme, SIGNAL(pressed()), this, SLOT(button_pressed()));
connect(ui->clickme, SIGNAL(released()), this, SLOT(button_released()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::button_clicked()
{
qDebug() < "Button Clicked";
}
void Dialog::button_pressed()
{
qDebug() < "Button Pressed";
}
void Dialog::button_released()
{
qDebug() < "Button Released";
}
#include <QtGui/QApplication>
#include "dialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
В файле dialog.h мы объявили три частных функции-слота - button_clicked(), button_pressed() и button_released(). Их реализация в файле dialog.cpp просто выводит отладочные сообщения, указывая на то, что событие наступило. В конструкторе класса Dialog мы соединили эти слоты с сигналами clicked(), pressed() и released() объекта clickme(QPushbutton). Указатель "ui" ссылается на окно диалога; при помощи него мы можем осуществлять доступ к дочерним виджетам точно таким же образом, как мы получили доступ к объекту clickme в функциях connect().
Первым аргументом функции connect() (статической функции класса QObject) является объект-источник сигнала, вторым аргументом является сам сигнал, третьим аргументом является объект-приемник сигнала, а последним аргументом - функция-слот. Скомпилируйте вышеприведенный код и запустите программу. Когда появится диалоговое окно, нажмите кнопку clickme и проверьте наличие отладочных сообщений в консоли. Вывод показывает, что все три сигнала генерируются при нажатии на кнопку pushbutton: сначала сигнал pressed, затем released и наконец clicked.
Окна сообщений (Message-boxes)
Перед тем, как рассматривать другие классы, относящиеся к графическому интерфейсу, нам необходимо упомянуть важный класс QMessageBox, который очень часто используется. Например, при закрытии несохраненного документа в приложениях на Qt появляется всплывающее окно, использующее этот класс, с вопросом: хотите ли вы сохранить документ или закрыть без сохранения. Главным образом этот виджет используется для предупреждения пользователя; он может показывать текст и иконки, пользователю даже может быть предоставлена возможность ввести какой-либо текст.
int res = QMessageBox::information(this,"Option", "Want to choose " + item + "?",QMessageBox::Yes | QMessageBox::No );
switch(res)
{
case QMessageBox::Yes:
ui->label_2->setText("You have chosen " + item);
break;
case QMessageBox::No:
ui->label_2->setText("You haven't made any choice.");
break;
}
Окно сообщения с заданным "уровнем строгости" создано. Аргументами конструктора класса QMessageBox являются: указатель на родительский класс, заголовок окна, текст сообщения и маска, составленная из элементов энумератора, таких, как 'Yes", "No", "Save", и.т.д., с помощью которой задаются кнопки окна сообщения.
Когда окно отображено и пользователь нажимает одну из кнопок, оно исчезает, а функция возвращает один из элементов энумератора, указывающий на то, какая кнопка была нажата пользователем - это и позволяет вам решить, что делать дальше при помощи оператора case, как показано выше.
Радио-кнопки (Radio buttons)
void Dialog::on_radioButton_clicked(bool checked)
{
if(checked)
item = ui->radioButton->text();
}
Вы можете выполнять действия в зависимости от значения переменной типа bool. Радио-кнопки используют "встроенный" виджет строки, поэтому вам не нужно использовать дополнительных виджетов для вывода текста рядом с кнопками.
Иногда необходимо выбрать сразу несколько вариантов из группы возможных - напрмер, пользователь выбирает три цвета из пяти. В этом случае радио-кнопки не подойдут и придется использовать виджет checkBox, который поддерживает два состояния и позволяет отмечать или не отмечать выбранные варианты. И снова сигнал clicked() генерируется при нажатии на кнопку, а переменная типа bool передается слоту. Код примера можно скачать по ссылке в примечании. Рисунки со 2 по 4 являются скриншотами получившегося приложения.
Рисунок 2: Кнопка выбора (CheckBox)
Рисунок 3: Радио-кнопки (RadioButtons)
Рисунок 4: Окно сообщения (MessageBox)
Помимо этих кнопок, в приложениях с графическим интерфейсом необходимы виджеты списков. Рассмотрим два виджета - раскрывающийся список (combo box) и список (list).
Раскрывающийся список предоставляет ниспадающее меню и показывает только выделенный элемент списка - в этом состоит достоинство виджета, поскольку он занимает минимум полезного пространства окна. В Qt этот виджет предоставляется классом QcomboBox. Элементы списка могут добавляться и удаляться также и во время исполнения программы. Сигнал генерируется в том случае, если пользователь меняет выбранный элемент. Если вы хотите предоставить пользователю возможность видеть сразу весь список, используйте класс QListWidget. Помотрите на Рисунок 5. Раскрывающийся список показывает только один элемент, а обычный список, представленный классом QListWidget - все элементы. Следующий код показывает, как добавлять элементы в эти списки...
ui->comboBox->addItem(ui->lineEdit->text());
QListWidgetItem * item = new QListWidgetItem( ui->lineEdit_2->text(), ui->listWidget); ui->listWidget->insertItem(ui->listWidget->count(), item);
Рисунок 5: Раскрывающийся список (ComboBox) и список (ListWidget)
