Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Диплом1.1.docx
Скачиваний:
15
Добавлен:
08.02.2016
Размер:
147.57 Кб
Скачать

2 Вибір проектних рішень

2.1 Структуна модель системи

Дана інформаційна система складається з наступних компонентів: головного віджету, ТСР серверу, класу взаємодії з ТСР сервером, класу обробки інформації що надходить від клієнта, обробника подій натискання на кнопку та функцій (рис. 2.1).

Головний віджет це клас, що відображає всі елементи графічного інтерфейсу в обраній користувачем структурі. На віджеті розташовані кнопки з функціями. Після натискання на будь яку кнопку, віджет викликає обробник подій. Обробник подій визначає на яку кнопку було натиснено і викликає функцію, яку має виконувати ця кнопка. Механізм реалізован за допомогою слотів сигналів.

У Qt використовується механізм - сигнали і слоти. Сигнал виробляється коли відбувається певна подія. Слот це функція, яка викликається у відповідь на певний сигнал. Виджеты Qt мають багато зумовлених сигналів і слотів, але ми завжди можемо зробити дочірній клас і додати наші сигнали і слоти в нім. Механізм сигналів і слотів типобезопасен. Сигнатура сигналу повинна співпадати з сигнатурою слота-одержувача. (Фактично слот може мати коротшу сигнатуру чим сигнал який він отримує, оскільки він може ігнорувати додаткові аргументи). Оскільки сигнатури порівнянні, компілятор може допомогти нам виявити неспівпадання типів. Сигнали і слоти слабо пов'язані. Клас, який виробляє сигнал не знає і не піклується про те, які слоти його отримають. Механізм сигналів і слотів Qt гарантує, що якщо ми підключимо сигнал до слота, слот буде викликаний з параметрами сигналу в потрібний час. Сигнали і слоти можуть приймати будь-яке число аргументів будь-якого типу. Вони повністю типобезопасны. Усі класи, успадковні від QObject або його дочірніх класів(наприклад, QWidget) можуть містити сигнали і слоти. Сигнали виробляються об'єктами коли вони змінюють свій стан так, що це може зацікавити інші об'єкти. При цьому він на знає і не піклується про те що у його сигналу може не бути одержувача.  Слоти можуть бути використані для отримання сигналів, але вони так само нормальні функції-члени. Так само як об'єкт не знає нічого про одержувачів своїх сигналів, слот нічого не знає про сигнали, які до нього підключені. Це гарантує що повністю незалежні компоненти можуть бути створені за допомогою Qt. Ми можемо підключати до одного слота стільки сигналів, скільки захочемо, також один сигнал може бути підключений до стількох слотів, скільки необхідно. Так само можливо підключати сигнал до іншого сигналу(це викличе вироблення другого сигналу негайно після появи першої). Клас, що наслідує від QObject має той же самийвнутрішній стан і забезпечує публічні методи для доступудо цього стану, але додатково у нього є підтримка длявикористання сигналів і слотів. Цей клас можеповідомити зовнішній світ що його стан змінивсявиробивши сигнал valueChanged() і у нього є слот, в якийінші об'єкти можуть посилати сигнали. Усі  класи, що   містять  сигнали  і  слоти  повинні  вказувати макрос Q _ OBJECT на початку їх опису. Вони такожмають бути нащадками(прямо або побічно) QObject. Ключове слово emit виробляє сигнал valueChanged()об'єкту з новим значенням в якості аргументу.У наступному прикладі ми створюємо два об'єкти типуCounter і сполучаємо сигнал valueChanged() першого ізслотом setValue() другого використовуючи статичнуфункцію QObject::connect().

Сигнали виробляються об'єктами коли вони змінюють свій стан так, що це може зацікавити інші об'єкти.  Тільки клас, який визначає сигнал або його нащадки можуть виробляти сигнал. Коли сигнал виробляється, слот, до якого він підключений зазвичай виконується негайно, так само як і нормальний виклик процедури. Коли це відбувається, механізм сигналів і сигналів і слотів повністю незалежний від будь-якого циклу подій графічного інтерфейсу. Виконання коду, наступного за випуском сигналу відбудеться відразу після виходу з усіх слотів. Ситуація злегка відрізняється коли використовуються відкладені з'єднання (queued connections); в цьому випадку код після ключового слова emit продовжує виконання негайно, а слоти будуть виконані пізніше. Якщо кілька слотів підключені до одного сигналу, слоти будуть виконані один за іншим у довільному порядку після вироблення сигналу. Сигнали автоматично генеруються програмою moc і не повинні бути реалізовані у вихідному коді. 

Вони можуть не повертати значення (тобто, використовуємо тип void). Зауваження з приводу аргументів: досвід показує, що сигнали і слоти легше повторно використовувати при написанні програм, якщо вони не використовують спеціальних типів. Наприклад, якби сигнал QScrollBar :: valueChanged () використав би спеціальний тип начебто гіпотетичного QScrollBar :: Range, він міг би бути підключеним тільки до слотів, спроектованим спеціально для нього.

Слот викликається коли виробляється сигнал, з яким він пов'язаний. Слот це звичайна функція в C + + і може викликатися звичайним способом; єдина його особливість, що з ним можна соедінсять сигнали. Так як слоти це нормальні функції-члени, вони слідують звичайним правилам C + + при прямому виклику. Тим не менш, як слоти, вони можуть бути викликані будь-яким компонентом, незалежно від їх рівнів доступу, через з'єднання сигнал-слот. Це означає, що сигнал, виработанностью об'єктом довільного класу може викликати захищений (private) слот об'єкта незв'язаного з ним класу.

Слоти так само можна оголошувати віртуальними, що іноді буває досить зручно. У порівнянні із зворотними викликами, сигнали і слоти злегка повільніше через збільшену гнучкості, яку вони забезпечують, хоча різниця для реальних додатків непомітна. Загалом, вироблення сигналу, який підключений до деяких слотам, в середньому в 10 разів повільніше, ніж виклик отримувача безпосередньо, при виклику не віртуальної функції. Ці накладні витрати потрібні для знаходження об'єкта, для безпечного перебору всіх його сполук (тобто перевірка що наступний одержувач не був знищений під час випуску сигналу) і передачі будь-яких параметрів у загальному вигляді. Хоча виклик десяти невіртуальний процедур може здатися дорогим, це менш затратно, ніж, наприклад, операція створення або видалення об'єкта. Поки ми створюємо рядок, вектор або список, що неявно вимагає створення об'єкта, витрати сигналів і слотів відповідають за дуже маленьку частку у витратах серед усіх викликів процедур. Те ж саме вірно робите ви системний виклик в слот або побічно викликаєте більше десяти функцій. На i586-500, ми можемо виробляти близько 2,000,000 сигналів в секунду, поєднаних з одним слотом або 1,200,000 в секунду, при з'єднанні в двома слотами. Простота і гнучкість механізму сигналів і слотів окупає додаткові витрати, які користувач програми навіть не помітить. Слід зауважити, що бібліотеки, які визначають змінні з іменами signal або slot, можуть викликати попередження або помилки компілятора при компіляції разом з програмою, написаною на Qt. Що б вирішити дану проблему, необхідно прибрати Визначенню заважають символу препроцесора за допомогою директиви # undef.

В деяких випадках може знадобитися інформація про відправника сигналу. Qtнадає функцію Qobject :: sender (), яка повертає покажчик на об'єкт, що пославсигнал. Клас QSignalMapper необхідний у ситуаціях, коли багато сигналів підключені до одного й того ж слоту, і цей слот повинен реагувати на кожен сигнал по-різному. Припустимо що у нас є три кнопки, які визначають, який файл ми хочемо відкрити:«Tax File», «Accounts File», or «Report File».

Що бвідкрити потрібний файл ми з'єднуємо їх сигнал QPushButton :: clicked () зіслотом readFilе(). Тепер використовуємо функцію класу QSignalMapper -setMapping () - для перетворення всіх сигналів в об'єкт QSignalMapper.

Рис. 2.1 Структурна модель системи

2.2 Вибір середовища програмування

Починаючи з версії 4.5 в комплект Qt включено середовище розробки Qt Creator, яке включає в себе редактор коду, довідку, графічні засоби Qt Designer і можливість зневадження застосунків. Qt Creator може використовувати GCC або Microsoft VC++ в якості компілятора і GDB як зневаджувач. Для Windows версій бібліотека комплектується компілятором, заголовними і об'єктними файлами MinGW. Qt Creator — середовище розробки, призначене для створення крос-платформових застосунків з використанням бібліотеки Qt. Підтримується розробка як класичних програм мовою C++, так і використання мови QML, для визначення сценаріїв в якій використовується JavaScript, а структура і параметри елементів інтерфейсу задаються CSS-подібними блоками.

Qt комплектується візуальним середовищем розробки графічного інтерфейсу Qt Designer, що дозволяє створювати діалоги і форми« мишею (в режимі WYSIWYG). У постачанні Qt є Qt Linguist — графічна утиліта, що дозволяє спростити локалізацію і переклад вашої програми багатьма мовами; і Qt Assistant — довідкова система Qt, що спрощує роботу з документацією по бібліотеці, а також дозволяє створювати крос-платформену довідку для розроблюваного на основі Qt ПЗ.

В Qt 4 введений новий набір класів для перегляду елементів використовуючих архітектуру модель / представлення для управління взаємозв'язком між даними та методом їх подання користувачеві. Поділ функціональності, введений в цій архітектурі, дає розробникам більшу гнучкість в налаштуванні відображення елементів і надає стандартний інтерфейс моделі, що дозволяє широкому діапазону джерел даних використовувати існуючі представлення елементів.

Архітектура Модель-Представлення-Контроллер (Model-View-Controller, MVC) є шаблоном проектування, що беруть початок від Smalltalk, який часто використовується для створення користувацьких інтерфейсів. У Design Patterns, Gamma та інших написано: MVC складається з трьох типів об'єктів. Модель - об'єкт програми, представлення - його екранне представлення і контролер - визначає реакцію інтерфейсу на користувальницький введення. До MVC при розробці користувальницького інтерфейсу ці об'єкти змішувалися разом. MVC розділяє їх, для збільшення гнучкості і можливості повторного використання.

Якщо об'єднати об'єкти представлення і контролера, то в результаті вийде архітектура модель / представлення. Це все ще відділяє спосіб зберігання даних від способу їх подання користувачеві, але забезпечує просту структуру, засновану на тих же принципах. Даний поділ дає можливість показати користувачеві одні й ті ж дані в різних представленнях і реалізувати нові типи представлень без зміни базової структури даних. Щоб забезпечити гнучкість управління користувальницьким введенням, ми представляємо концепцію делегата (delegate). Перевага наявності делегата в цій структурі полягає в тому, що це дає можливість для налаштування представлення та редагування елементів даних.

Модель здійснює з'єднання з джерелом даних, надаючи необхідний інтерфейс іншими компонентами архітектури. Характер зв'язку залежить від типу джерела даних і способу реалізації моделі.

З моделі представлення отримує модельні індекси, які є посиланнями на елементи даних. Передаючи модельні індекси моделі, представлення може отримати елементи даних з джерела даних.

У стандартних представленнях делегат відображає елементи даних. Якщо елемент редагований, делегат зв'язується з моделлю безпосередньо використовуючи модельні індекси.

Як правило, класи модель / представлення можуть бути розділені на три описані вище групи: моделі, представлення та делегати. Кожен з цих компонентів описується абстрактним класом, що надає загальний інтерфейс і, в деяких випадках, особливості реалізації за замовчуванням. Абстрактні класи мають на увазі успадкування від них в порядку, що надає повний набір функціональності, очікуваної іншими компонентами; це дозволяє також писати спеціалізовані компоненти.

Моделі, представлення та делегати взаємодіють один з одним використовуючи сигнали і слоти:

  • Сигнали від моделі інформують представлення про зміни даних у джерелі даних.

  • Сигнали від представлення надають інформацію про користувальницький взаємодії з відображеними елементами.

  • Сигнали від делегата використовуються під час редагування, повідомляють моделі і представлення про стан редактора.

Всі моделі елементів засновані на класі QAbstractItemModel. Цей клас визначає інтерфейс, використовуваний представленнями і делегатами для доступу до даних. Самі дані не повинні зберігатися в моделі; вони можуть зберігатися в структурі даних або сховищі, що надається окремим класом, файлі, базі даних або будь-якому іншому прикладному компоненті.

QAbstractItemModel забезпечує досить гнучкий інтерфейс до даних для обробки представлень, які представляють дані у вигляді таблиць, списків і дерев. Однак, при реалізації нових моделей у вигляді структур списків і таблиць, класи QAbstractListModel і QAbstractTableModel слугуватимуть кращою відправною точкою, так як вони надають реалізації відповідних функцій за умовчанням. На основі кожного з цих класів можна створити підкласи для надання моделей, що підтримують специфічні види списків і таблиць.

Qt надає кілька готових моделей, які можуть використовуватися для обробки елементів даних:

  • QStringListModel використовується для зберігання простого списку елементів QString.

  • QStandardItemModel управляє більш складними деревовидними структурами елементів, кожен з яких може містити довільні дані.

  • QDirModel надає інформацію про файлах і директоріях локальної файлової системи.

  • QSqlQueryModel, QSqlTableModel і QSqlRelationalTableModel використовуються для доступу до баз даних, що враховує угоди архітектури модель / подання.

Якщо ці стандартні моделі не відповідають вашим вимогам, то для створення своїх власних моделей ви можете створити підклас QAbstractItemModel, QAbstractListModel або QAbstractTableModel.

Надаються повні реалізації для різних видів представлень: QListView відображає список елементів, QTableView відображає дані моделі у вигляді таблиці, а QTreeView відображає елементи моделі у вигляді ієрархічного списку. Кожен з цих класів заснований на базовому абстрактному класі QAbstractItemView. Хоча ці класи і готові до використання, вони можуть мати підкласи, для більш точного налаштування представлення.

QAbstractItemDelegate - це абстрактний базовий клас делегата в структурі модель / представлення. Реалізація делегата за замовчуванням надається класом QItemDelegate, який використовується в якості делегата за замовчуванням в стандартних представленнях Qt.

В архітектурі модель / представлення є два підходи до сортування; який підхід вибрати - залежить від вашої базової моделі.

Якщо вашу модель можливо сортувати, тобто якщо вона заново реалізує функцію QAbstractItemModel :: sort (), то і QTableView і QTreeView надають API, що дозволяє програмно сортувати дані вашої моделі. Крім того, ви можете дозволити інтерактивне сортування (interactive sorting) (тобто дозволити користувачам сортувати дані натискаючи на заголовки представлення), з'єднавши сигнал QHeaderView :: sectionClicked () зі слотом QTableView :: sortByColumn () або ж зі слотом QTreeView :: sortByColumn (), відповідно.

Альтернативний підхід, якщо ваша модель не має необхідного інтерфейсу або ви хочете використовувати представлення списку для відображення ваших даних, полягає у використанні моделі-посередника для перетворення структури вашої моделі перед передачею даних до представлення.

Безліч допоміжних класів успадковані від класів стандартних представлень для зручності використання в додатках, що залежать від заснованих на елементах представлення Qt і класах таблиць. Вони не призначені для створення на їх основі підкласів, а існують просто як еквівалент класів Qt3, що працюють за старою схемою. Прикладами таких класів служать QListWidget, QTreeWidget і QTableWidget, що реалізують поведінку, подібне поведінки класів Qt 3 QListBox, QListView і QTable.

Ці класи менш гнучкі, ніж класи представлень і не можуть використовуватися з довільними моделями. Якщо ви не сильно потребуєте в наборі заснованих на елементах класів, ми рекомендуємо використовувати при обробці даних в представленнях елементів підхід на основі модель / представлення.

Якщо ж ви хочете скористатися перевагами розділення даних і представлення не відмовляючись від схеми явного попереднього заповнення даних, як наприклад QListView, QTableView і QTreeView з моделлю QStandardItemModel.

Qt маэ зручний механызм створення ынтервейсу программи QStyle відокремлений від віджетів, що дає можливість малювати елементи управління на будь-якому контексті малювання. Це може знадобитися, наприклад, в тих ситуаціях, коли ви розробляєте свій віджет і хочете, щоб він був успадкований від одного класу, а виглядав як інший елемент управління, доступний в Qt. Насамперед ми створюємо об'єкт класу QStylePainter, цей клас знає і про поточний стилі керування, і про об'єкт класу QPainter. Потім ми створюємо об'єкт QStyleOptionPushButton, тому що хочемо намалювати кнопку. Виклик методу initFromO справить копіювання опцій віджета, таких як: прямокутна область, палітра, шрифт, стан і т. д. Це найшвидший спосіб ініціалізації.  Разом з тим, одна з опцій ініціалізується текстом "This is a label". На закінчення викликається метод drawControl () з об'єкта класу QStylePainter, який малює кнопку натискання. Використання каскадного стилю документа Реалізація власного стилю може виявитися дуже складним, копіткою і стомлюючим заняттям. Цей факт послужив поштовхом для впровадження в Qt нового способу створення стилю. За основу був узятий CSS (Cascading Sty'e Sheets, каскадний стиль документа), що використовується в HTML. В Qt цю мову був адаптований для віджетів, але концепція та синтаксис мови залишилися тими ж. Це дозволило повністю відокремити створення стилю від програми. Більш того, для створення стилю знання С + + зовсім не обов'язково, що дозволяє залучити для роботи над додатком дизайнерів, які не мають навичок програмування. Програма Qt Designer надає можливість інтеграції CSS-стилів, що спрощує можливість перегляду на прикладах різних віджетів. За своєю суттю, каскадний стиль є не що інше, як текстовий опис стилю. Цей опис може знаходитися в окремому файлі, зазвичай мають розширення qss. Його можна встановити в додатку за допомогою методу QApplication :: setStyleSheet (), або в окремому віджеті за допомогою ана-логічного методу QWidget :: setStyleSheet (). Директива називається селектором. Вміст фігурних дужок, що знаходяться праворуч від назви віджета, називається визначенням селектора. Селектор визначає, для якого з віджетів буде використовуватися визначення.  Визначення складається з властивостей і значень, а якщо їх декілька, то вони відокремлюються один від одного крапкою з комою, наприклад: Якщо в різних селекторах використовуються однакові визначення, то їх можна згрупувати в єдину директиву. Каскадний стиль не чутливий до регістру, наприклад: COLOR = color, = COLOR і т. д. Виняток становлять лише імена класів. Для завдання стилю складових елементів управління необхідно отримати доступ до його піделементи, таким як, наприклад, кнопка зі стрілкою елемента списку QComboBox. QComboBox :: drop-down {image: url (dropdown.png)} Також можна вказувати стану, тобто визначення повинне застосовуватися до віджету тільки в тому випадку, якщо він знаходиться в певному (вказаному) стані. Бібліотека Qt надає можливість використання в програмах різних стилів (Look &Feel) і їх зміни в процесі  роботи програми.  Стиль може встановлюватися як длявсього програми, так  і  для  кожного  віджета  окремо.  Як  правило, один  стильвстановлюється  відразу всім  віджетів  програми, для чого використовується статичний  метод  QApplication  ::  setstyle (). У кожен  з методів передається  ряд  тпараметрів, що надають всю необхідну інформацію  длявідображення  віджетів.  Вся  необхідна  додаткова  інформація  доступна  в  об'єктах класу  QStyleOption. Qt надає і більш простий  спосіб реалізації стилів,  якийбазується  на   каскадномустилі  документа CSS. Каскадний стиль  складається з тпослідовності т правил  тстилю. Правило  стилю  задається вибором і визначенням.

2.4 Вимоги до системи

Вимоги до апаратного забезпечення: процесор Intel Pentium 3 з тактовою частотою 1000 MHz(x86) або аналогічний, оперативна пам’ять не менше 128 MB, відео адаптер VGA @ 1024x780 з відео пам’яттю не менше 64 MB, місце на жорсткому диску 300 MB.

Вимоги до програмного забезпечення: даний проект є крос-платформним програмним забезпеченням, тому для його роботи підійде будь-яка сучасна операційна система, на комп’ютері иає бути встановлений драйвер Qt.