Чтение онлайн

ЖАНРЫ

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

2. Пользовательский виджет

В специализированных приложениях часто требуется показывать данные в пользовательском виджете. Например, программа редактирования пиктограмм могла бы в качестве центрального использовать виджет IconEditor. В главе 5 рассматриваются способы написания пользовательских виджетов с помощью средств разработки Qt.

3. Базовый виджет QWidget с менеджером компоновки

Иногда в центральной области приложения размещается много виджетов. Это можно сделать путем применения QWidget в качестве родительского виджета по отношению ко всем другим виджетам и использовать менеджеры компоновки для задания

дочерним виджетам их размера и положения.

4. Разделитель

Другой способ размещения в центральной области нескольких виджетов заключается в применении разделителя QSplitter. QSplitter размещает свои дочерние виджеты по горизонтали или по вертикали и предоставляет пользователю некоторые возможности по управлению размерами виджетов. Разделители могут содержать любые виджеты, включая другие разделители.

5. Рабочая область (workspace) интерфейса MDI

Если в приложении используется интерфейс MDI, центральную область будет занимать виджет QWorkspace, а каждое окно интерфейса MDI будет являться дочерним виджетом.

Менеджеры компоновки, разделители и рабочие области MDI могут использоваться совместно со стандартными виджетами Qt или с пользовательскими виджетами. В главе 6 подробно рассматриваются эти классы.

В приложении Электронная таблица в качестве центрального виджета применяется некоторый подкласс класса QTableWidget. Класс QTableWidget уже обеспечивает большинство необходимых нам функций электронной таблицы, но он не может понимать формулы электронной таблицы вида «=Al+A2+A3» и не поддерживает операции с буфером обмена. Мы реализуем эти недостающие функции в классе Spreadsheet, который наследует QTableWidget.

Создание подкласса QTableWidget

Класс Spreadsheet наследует QTableWidget. Виджет QTableWidget фактически является сеткой, представляющей собой двумерный разряженный массив. На нем отображается часть ячеек всей сетки, полученная при прокрутке изображения пользователем. При вводе пользователем текста в пустую ячейку QTableWidget автоматически создает элемент QTableWidgetItem для хранения текста.

Давайте начнем с реализации виджета и сначала приведем заголовочный файл:

01 #ifndef SPREADSHEET_H

02 #define SPREADSHEET_H

03 #include <QTableWidget>

04 class Cell;

05 class SpreadsheetCompare;

Заголовочный файл начинается с предварительных объявлений классов Cell и SpreadsheetCompare.

Рис. 4.1. Деревья наследования для классов Spreadsheet и Cell.

Такие атрибуты ячейки QTableWidget, как ее текст и выравнивание, хранятся в QTableWidgetltem. В отличие от QTableWidget, класс QTableWidgetltem не является виджетом; это обычный класс данных. Класс Cell наследует QTableWidgetltem, и мы рассмотрим

этот класс в последнем разделе данной главы, где представим его реализацию.

06 class Spreadsheet : public QTableWidget

07 {

08 Q_OBJECT

09 public:

10 Spreadsheet(QWidget *parent = 0);

11 bool autoRecalculate const { return autoRecalc; }

12 QString currentLocation const;

13 QString currentFormula const;

14 QTableWidgetSelectionRange selectedRange const;

15 void clear;

16 bool readFile(const QString &fileName);

17 bool writeFile(const QString &fileName);

18 void sort(const SpreadsheetCompare &compare);

Функция autoRecalculate реализуется как встроенная (inline), поскольку она лишь показывает, задействован или нет режим автоматического перерасчета.

В главе 3 мы опирались на использование некоторых открытых функций класса электронной таблицы Spreadsheet при реализации MainWindow Например, из MainWindow::newFile мы вызывали функцию clear для очистки электронной таблицы. Кроме того, мы вызывали некоторые функции, унаследованные от QTableWidget, а именно setCurrentCell и setShowGrid.

19 public slots:

20 void cut;

21 void copy;

22 void paste;

23 void del;

24 void selectCurrentRow;

25 void selectCurrentColumn;

26 void recalculate;

27 void setAutoRecalculate(bool recalc);

28 void findNext(const QString &str, Qt::CaseSensitivity cs);

29 void findPrevious(const QString &str, Qt::CaseSensitivity cs);

30 signals:

31 void modified;

Класс Spreadsheet содержит много слотов, которые реализуют действия пунктов меню Edit, Tools и Options, и он содержит один сигал modified для уведомления о возникновении любого изменения.

32 private slots:

33 void somethingChanged;

Мы определяем один закрытый слот, который используется внутри класса Spreadsheet.

34 private:

35 enum { MagicNumber = 0x7F51C883, RowCount = 999, ColumnCount = 26 };

36 Cell *cell(int row, int column) const;

37 QString text(int row, int column) const;

38 QString formula(int row, int column) const;

39 void setFormula(int row, int column, const QString &formula);

40 bool autoRecalc;

41 };

В закрытой секции этого класса мы объявляем три константы, четыре функции и одну переменную.

Поделиться с друзьями: