Самарев Р.С. - Программирование с использованием библиотеки Qt (1075627), страница 4
Текст из файла (страница 4)
Например,метка с текстом «&Save» обозначает, что при нажатии комбинации Alt-S фокусввода будет установлен на тот элемент, который связан с этой меткой;-редактирование порядка следования элементов при использовании клавиши Tab(Edit Tab Order).Переключим QtDesigner в режим сигналов и слотов и обеспечим связывание элементов. Для того чтобы установить связь, необходимо нажать левой клавишей мыши наэлемент источник, после чего не отпуская переместить появившуюся стрелку на элементполучатель. В открывшемся окне выбрать пару сигнал и соответствующий ему слот.Определим следующие пары:dial, SIGNAL(sliderMoved(int)) – spinBox, SLOT(setValue(int))spinBox, SIGNAL(valueChanged(int)) – dial, SLOT(setValue(int))btnExit, SIGNAL(clicked()) – DialogEx2, SLOT(reject())spinBox, SIGNAL(valueChanged(QString)) – textEdit, SLOT(append(QString))Результат, который должен получиться, показан на рисунке 15.Оглавление20Рисунок 15 – Связывание сигналов и слотов элементов формы ex2 в QtDesignerПроводим проверку формы в режиме просмотра.
При изменении величины вQSpinBox должно синхронно меняться положение в QDial и наоборот. Кроме того, всемгновенные значения регистрируются в элементе QTextEdit. На рисунке 16 демонстрируется результат, который должен быть получен, если все сделано правильно. Полученнуюформу сохраняем в файл под именем ex2.ui.Рисунок 16 – Проверка работоспособности формы ex2Полученная форма пока еще работает автономно и не представляет практическогоинтереса. Необходимо написать код программы, обеспечивающий её интеграцию. Предположим, что необходимо разработать класс-виджет, обеспечивающий отображение разработанной формы и, кроме того, переопределяющий реакцию на нажатие кнопки.Воспользуемся любым текстовым редактором и создадим заголовочный файлdialogex2.h:Оглавление21#ifndef DIALOG_EX2_H#define DIALOG_EX2_H#include <QDialog>#include "ui_ex2.h" // заголовок сгенерированный uic автоматическиclass DialogEx2 : public QDialog, public Ui::DialogEx2{Q_OBJECTpublic:DialogEx2( QWidget * parent = 0);private slots:void onExitClicked();};#endifОпределяем класс DialogEx2 потомком классов QDialog (стандартный диалог) исформированныйавтоматическикомпиляторомuicпосозданнойформеклассUi::DialogEx2, в котором описана последовательность создания формы.
Его реализациюможно увидеть в файле ui_ex2.h, который появится после работы uic. Определим слот, который будет обеспечивать реакцию на нажатие кнопки – onExitClicked(). Имя слота можетбыть выбрано произвольно.Описываем реализацию класса DialogEx2 в файле dialogex2.cpp:#include <QtGui>#include <dialogex2.h>// Преобразуем входную последовательность символов в кодировку UNICODE#define RUS( str ) codec->toUnicode(str)DialogEx2::DialogEx2(QWidget * parent):QDialog(parent){setupUi(this); // Строим форму, описанную в Ui_DialogEx2// связываем сигнал кнопки со слотом onExitClickedconnect(pushButton, SIGNAL(clicked()), this, SLOT(onExitClicked()));};void DialogEx2::onExitClicked(){QTextCodec * codec = QTextCodec::codecForName("Windows-1251");// Спрашиваем, закрывать приложение или нетif( QMessageBox::question ( this, QString(),RUS("Завершить приложение?"), QMessageBox::Yes|QMessageBox::No) ==QMessageBox::Yes )exit(0);};Оглавление22Примечание - В тексте программы используется имя кнопки btnExit к,В отдельном файле реализуем создание объекта приложения и отображение формы.
Файл ex2.cpp содержит следующий код:#include <QApplication>#include <QSplitter>#include "dialogex2.h"int main(int argc, char *argv[]){QApplication app(argc, argv);1)//Отображаем форму так, как сделано в QtDesignerDialogEx2 * dialog1 = new DialogEx2();dialog1->show();2)// Отображаем две формы горизонтально с вертикальным разделителемQSplitter * splitter = new QSplitter(Qt::Horizontal);DialogEx2 * dialog1 = new DialogEx2();DialogEx2 * dialog2 = new DialogEx2();splitter->addWidget( dialog1 );splitter->addWidget( dialog2 );splitter->show();return app.exec();// отображаем окно// запускаем цикл обработки сообщений}Обратите внимание, что в функции присутствуют два взаимно исключающих блокасоздания диалога DialogEx2.
Первый вариант – очевиден и приведет к появлению формы втаком виде, как она была создана в QtDesigner. Второй вариант иллюстрирует возможность использования формы в качестве подчиненного элемента для другого виджета. Вчастности, QSplitter – виджет, обеспечивающий разделение двух других виджетов, причемграница между ними может быть перемещена пользователем с помощью мыши.
Представленный выше фрагмент кода реализует в качестве виджетов и использует две формы типаDialogEx2 (см. рисунок 17).Оглавление23Рисунок 17 – Приложение ex2 с двумя формами с разделителем3.3Сборка приложенияДля того чтобы собрать приложение, необходим файл проекта ex2.pro, который может быть сформирован автоматически командой qmake –project или быть таким как представлено ниже:TEMPLATE = appTARGET = ex2CONFIG += release# InputHEADERS += dialogex2.hFORMS += ex2.uiSOURCES += dialogex2.cpp ex2.cppОкончательная сборка проекта производится командами qmake ex2.pro и nmake.Недостатками использования QtDesigner для генерации форм являются ограниченные функциональные возможности и плохо управляемый и не оптимальный код программы в части реализации методов классов форм.3.4ЗаданиеИзмените тип разделителя с QSplitter(Qt::Horizontal); на QSplitter(Qt::Vertical); изафиксируйте полученный результат.Оглавление244Разработка калькулятора4.1Исходные данныеРассмотрим создание более сложного приложения, наглядно иллюстрирующеговозможности библиотеки Qt в части компактного кода программы и динамического создания элементов управления.
Разработаем калькулятор, внешний вид которого представленна рисунке 18.Рисунок 18 – Приложение КалькуляторФорму приложения реализуем на основе класса Qdialog. При этом воспользуемсяклассом QSignalMapper, позволяющим в данном случае унифицировать процесс обработки нажатий кнопок, направив сигналы от всех кнопок на единственный слотvoid clicked(int id), параметром которого будет идентификатор кнопки. Число будем отображать в элементе m_pLineEdit, имеющим тип QLineEdit*.Заголовочный файл calcDialog.h с описанием класса CalcDialog представлен ниже:#ifndef _CALC_DIALOG_H_#define _CALC_DIALOG_H_#include <QDialog>#include <QLineEdit>#include <QSignalMapper>/// Класс, реализующий калькуляторclass CalcDialog: public QDialog{Q_OBJECTОглавление25public:CalcDialog( QWidget * parent = 0);virtual ~CalcDialog(){};protected:QSignalMapper * m_pSignalMapper;QLineEdit* m_pLineEdit;double m_Val; ///< Значение, с которым будет выполнена операцияintm_Op;///< Код нажатой операцииboolm_bPerf;///< Операция была выполнена.
Надо очистить поле вводаvoidinitNum();///< Инициализировать переменные, связанные с вычислениямиdouble getNumEdit();void///< Получить число из m_pLineEditsetNumEdit( double ); ///< Отобразить число в m_pLineEdit/// Вычислить предыдущую операцию///(в бинарных операциях был введен второй операнд)voidcalcPrevOp( int curOp );/// Проверить, была ли выполнена операция при нажатии на цифровую клавишу/// Если операция выполнена, значит m_pLineEdit необходимо очиститьvoidcheckOpPerf();private slots:/// Слот для обработки нажатий всех кнопокvoid clicked(int id);};#endifПри создании кнопок необходимо обеспечить их правильное размещение. Воспользуемся средствами Qt и создадим схемы размещения виджетов в соответствии с рисунком19.Таблица 1 – Назначение схем выравниванияИмя объектаКлассgridLayoutbccKeysLayoutQGridLayoutQHBoxLayoutНазначениеЦифровые кнопки и кнопки операцийКнопки удаления последней цифры, сброс теку-mainKeysLayoutdlgLayoutQHBoxLayoutQVBoxLayoutщего значения и сброс операцииЦифровые кнопки + кнопка выполнения «=»Вертикальное размещение элемента QLineEditи групп кнопок bccKeysLayout и mainKeysLayoutОглавлениеdlgLayout26bccKeysLayoutgridLayoutmainKeysLayoutРисунок 19 – Схемы выравнивания кнопок калькулятораРеализуем основную программу – файл calcDialog.cpp.