Как настроить смартфоны и ПК. Информационный портал
  • Главная
  • Новости
  • Создание приложений с графическим интерфесом. Создание графического интерфейса средствами Qt C clr создание графического интерфейса

Создание приложений с графическим интерфесом. Создание графического интерфейса средствами Qt C clr создание графического интерфейса

5

Я сделал много разных разделов GUI-системы для Nintendo DS, таких как кнопки и текстовые поля и флажки, но мне нужен способ скрыть эти классы в одном классе Gui, чтобы я мог рисовать все на экране все сразу, и сразу проверьте все кнопки, чтобы проверить, нажаты ли какие-либо кнопки. Мой вопрос - как наилучшим образом организовать все классы (например, кнопки и текстовые поля) в один GUI-класс?

Вот один способ, которым я думал, но это не кажется правильным:

Edit: Я использую C++.

Class Gui { public: void update_all(); void draw_all() const; int add_button(Button *button); // Returns button id void remove_button(int button_id); private: Button *buttons; int num_buttons; }

Этот код имеет несколько проблем, но я просто хотел дать вам представление о том, чего я хочу.

  • 5 ответов
  • Сортировка:

    Активность

2

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

Я какое-то время что-то искал, я консультировался с некоторыми книгами и VTMs , и до сих пор это приблизительная идея простых систем ui.

Class uiElement() { ... virtual void Update() = 0; virtual void Draw() = 0; ... } class uiButton() public: uiElement { ... virtual void Update(); virtual void Draw(); ... } class uiTextbox() public: uiElement { ... virtual void Update(); virtual void Draw(); ... } ... // Other ui Elements class uiWindow() { ... void Update(); void Draw(); void AddElement(uiElement *Element); void RemoveElement(uiElement *Element); std::list Elements; ... } void uiWindow::Update() { ... for (list ::iterator it = Elements.begin(); it != Elements.end(); it++) it->Update(); ... } void uiWindow::Draw() { ... for (list ::iterator it = Elements.begin(); it != Elements.end(); it++) it->Draw(); ... }

princple является создание окна и attact элементов пользовательского интерфейса к нему, и вызвать отрисовки и обновление методы из соответствующих основных функций.

У меня пока ничего не работает, так как у меня проблемы с кодом рисования. С различными API-интерфейсами на ПК и PSP я просматриваю код оболочки для OpenGL и psp gu.

Надеюсь, это поможет.

0

Одна полезная стратегия, которую следует иметь в виду, может быть composite pattern . На низком уровне он может позволить вам легче обрабатывать все объекты GUI (и коллекции объектов) после их создания. Но я не знаю, что связано с дизайном графического интерфейса GUI, поэтому одно место, чтобы найти общее вдохновение, - это исходный код существующего проекта. WxWidgets - это кросс-платформенный графический интерфейс с доступным исходным кодом. Удачи с вашим проектом!

0

3

Для тех, кто заинтересован, вот мой с открытым исходным кодом, BSD-лицензированные GUI инструментарий для DS:

Ответ на предмет2k довольно хорош, но я бы серьезно рекомендовал иметь код, содержащий элементы дочернего интерфейса в базовом классе uiElement. Это образец, за которым я следил в Вупси.

Если вы не поддержите это в базовом классе, вы столкнетесь с серьезными проблемами при попытке реализовать что-либо более сложное, чем текстовое поле и кнопку. Например:

  • Табличные панели можно смоделировать как несколько кнопок, сгруппированных в единый родительский элемент пользовательского интерфейса, который обеспечивает взаимную исключительность выбора;
  • Группы радиостанций (с течением времени);
  • Полосы прокрутки могут быть представлены как элемент слайдера/желоба и кнопки вверх/вниз;
  • Списки прокрутки могут быть представлены в виде контейнера и нескольких элементов пользовательского интерфейса.

Кроме того, стоит помнить, что у DS есть процессор с частотой 66 МГц и 4 МБ ОЗУ, который используется как для хранения вашей программы, так и для ее выполнения (DS-диски загружаются в ОЗУ до их запуска). Вы действительно должны рассматривать его как встроенную систему, что означает, что STL отсутствует. Я удалил STL из Woopsi и сумел сохранить 0.5MB. Не так много по настольным стандартам, но это 1/8 от общей доступной памяти DS, потребляемой STL-мусором.

Я подробно весь процесс написания пользовательского интерфейса на моем блоге:

Она включает в себя описание двух алгоритмов я придумал для перерисовки экрана, который хитрая часть создание графического интерфейса (одно просто разбивает прямоугольники вверх и запоминает видимые области, а другое использует деревья BSP, что намного эффективнее и проще для понимания), советы по оптимизации и т. д.

Аннотация: Изучаются выджеты - визуальные элементы, из которых состоит графический интерфейс пользователя, их компоновка, политика размеров, сигнально-слотовые соединения, элементы графического интерфейса и их использование.

13.1 Виджеты (Widgets)

Виджеты (Widgets ) - это визуальные элементы, из которых состоит графический интерфейс пользователя.

Примеры виджетов:

  • Кнопка (класс QPushButton );
  • Метка (класс QLabel );
  • Поле ввода (класс QLineEdit );
  • Числовое поле-счётчик (класс QSpinBox );
  • Строка прокрутки (класс QScrollBar ).

В Qt есть около 50-ти готовых классов графических элементов доступных для использования. Родительским классом для всех виджетов является класс QWidget . От него наследуются все главные свойства визуальных элементов, которые мы тщательно рассмотрим. Исследование способов разработки программ с графическим интерфейсом начнём с примера.

Создадим пустой файл проекта. Запустим мастера проектов и выберем в разделе Projects (Проекты) пункт Other Project (Другой проект) . Далее выберем тип проекта Empty Qt Project (Пустой проект Qt) . К файлу проекта добавим содержимое:

TEMPLATE = app #Модули Qt, которые мы будем использовать QT += widgets #Добавляем модуль widgets для работы с виджетами (необходимо для Qt5). TARGET = widget#Название исполняемого файла SOURCES += \ main.cpp

Теперь создадим простую программу с окном, в котором мы будем выводить надпись. Установим размер окна и текст его заголовка, а также установим шрифт для надписи. Для этого создадим файл main.cpp со следующим содержанием:

#include #include int main (int lArgc, char * lArgv ) { //Создаём объект QApplication, который инициализирует и настраивает оконную программу, //управляет её выполнением с помощью цикла обработки событий QApplication lApplication (lArgc, lArgv); QLabel lLabel; //Создаём виджет QLabel - метка lLabel.setText (" I am widget! "); //Задаём текст для метки lLabel.setGeometry (200, 200, 300, 150); //Задаём размеры - позицию (x, y) ширину и высоту. Задаём выравнивание текста lLabel.setAlignment (Qt::AlignHCenter | Qt::AlignVCenter); //Класс QFont используют для настройки параметров шрифта. //Выбираем семейство шрифтов Arial Black и размер 12. QFont lBlackFont (" Arial Black ", 12); lLabel.setFont (lBlackFont); //Задаём шрифт для метки lLabel.show (); //Вызываем метод show() для показа метки на экране. return lApplication.exec (); //Запускаем программу на выполнение exec() выполняет //цикл обработки событий. Программа ожидает действия пользователя и выполняет их обработку. }

Как видим, элементы, из которых состоят интерфейсы в Qt , имеют собственные позицию и размер - так называемую "геометрию" - и, таким образом, занимают соответствующую прямоугольный участок на экране (см. рис. 13.1). Также каждый из элементов имеет настройки, которые определяют его поведение и вид.


Рис. 13.1.

Для создания структуры виджеты организовывают в иерархию по принципу "часть - целое". Каждый из виджетов может содержать другие виджеты. Такой визуальный элемент становится "родителем" (родительским виджетом) для элементов, которые он содержит. Отметим, что такие отношения не следует путать с наследованием в C++ - отношениями между классами в программе. Отношения между виджетами являются отношениями между объектами. Такие отношения порождают несколько последствий:

  • родительский элемент будет отвечать за удаление дочернего элемента: если родительский виджет удалят - то он автоматически удалит и все дочерние элементы;
  • родительский виджет размещает дочерние виджеты внутри себя, части дочерних виджетов, которые выходят за пределы родителя будут невидимыми;
  • часть состояния родительского виджета передаётся дочерним - это касается некоторых свойств (видимость, активность) и стилей, которые накладываются на визуальный элемент.

Виджеты, которые не имеют родителя (виджеты верхнего уровня), имеют вид отдельных окон в программе. Рассмотрим пример. Назовём новый проект ParentExample . Файл проекта будет содержать обычные для GUI -проекта настройки:

TEMPLATE = app TARGET = ParentExample QT += widgets

Для виджета, который мы будем использовать в качестве главного окна создадим новый класс. Для этого в категории Files and Classes (Файлы и классы) выберем раздел С++ и выберем С++ Class (см. рис. 13.2).

Следующим шагом будет создание нескольких элементов на окне. Для этого откроем файл parentwidget.cpp и изменим код конструктора класса. Для отображения элементов достаточно создать их в конструкторе класса и задать ParentWidget как отца для них. Код parentwidget.cpp выглядит так:

#include " parentwidget.h " #include #include #include ParentWidget::ParentWidget (QWidget * parent) : QWidget (parent) { //Создаём метку, указывая родительский виджет - this, то есть экземпляр класса ParentWidget. QLabel * lLabel=new QLabel (this); //Позиция относительно левого верхнего угла родительского виджета. lLabel ->setGeometry (50, 0, 100, 30); lLabel ->setText (" TextLabel "); //Текст на метке. //Создаём кнопку, задаём "родителя", геометрию и текст QPushButton * lPushButton = new QPushButton (this); lPushButton->setGeometry (50, 50, 100, 30); lPushButton->setText (" PushButton "); //Создаём поле ввода, задаём "родителя", геометрию и текст QLineEdit * lLineEdit = new QLineEdit (this); lLineEdit ->setGeometry (50, 100, 100, 30); lLineEdit ->setText (" LineEdit "); lLineEdit ->selectAll (); //Выделяем текст в поле ввода (просто для примера) //Наконец изменяем размер родительского виджета setGeometry (x (), y (), 300, 150); //и задаём текст заголовка окна setWindowTitle (" parent widgetExample "); }

Поскольку родительским элементом является ParentWidget , то метка (QLabel ), кнопка (QPushButton ) и текстовое поле (QLineEdit) находятся в его пределах. Позицию дочерних виджетов задают относительно левого верхнего угла отца. В этом легко убедиться изменив размеры и позицию окна нашей программы. Обратите внимание на то, как мы создавали элементы пользовательского интерфейса в динамической памяти используя оператор new . Это гарантирует, что элементы не будут удалены после завершения работы конструктора ParentWidget .

Сразу оговорюсь, что C++ мой любимый язык, я на нем пишу практически «с детства» и отрицать его важность, как лучшего одного из лучших языков для написания программ для любых целей, не буду. Тем более не вижу смысла начинать очередной холивар или меряться «указками». Это статья - лишь описание неудачного опыта работы с языком, объясняющая некоторые его аспекты, знание которых поможет другим программистам в будущем.

Однажды я столкнулся с развивающейся библиотекой GUI класса. С точки зрения C++, а точнее его классов, экземпляров и иерархий, этот язык представляется невероятно близким к концепции управления GUI, в частности таким элементам, как виджеты, окна классов и подокна. OO модели C++ и оконной системы тем не менее разные. C++ был задуман как «статический» язык с охватом лексем, статической проверкой типов и иерархий определенных во время компиляции. Окна и их объекты с другой стороны, по своей природе динамичны, они обычно живут за рамкам отдельной процедуры или блока, с помощью которой были созданы; иерархии виджетов в значительной степени определены расположением, видимостью и потоками событий. Основы графического пользовательского интерфейса, такие как динамические и геометрические иерархии окон и управления, протекания событий, не поддерживаются непосредственно синтаксисом С++ либо его семантикой. Таким образом, эти функции должны быть воспроизведены в коде C++ GUI. Это приводит к дублированию графического инструментария, или функциональности оконного менеджера, код «раздувается», мы вынуждены отказываться от многих «сильных» особенностей C++ (например, проверки типов во время компиляции). В статье приведено несколько простых примеров C++ / GUI «не стыковок».

Не создавайте конструкторы (или, по крайней мере, не используйте их)

Когда полученный класс переопределяет виртуальный метод родительского класса, надо иметь в виду, что переопределение не вступает в силу, пока конструктор базового класса выполняется. Это особенно раздражает, когда объекты запрашивают виджеты, которые реагируют на события GUI. Предположим, что класс Basic_Window был предназначен для создания ванильного черно-белого окна на экране:

Class Basic_Window {
public:
Basic_Window(Rect rect) { gt_create_window(rect,visible,this); }
virtual void handle_create_event() { set_background(WHITE); }
};

Здесь gt_create_window() отвечает за низкоуровневый вызов основного графического инструментария (например, xvt_win_create() ). Эта функция выделяет место под данные инструментария, уведомляет оконный менеджер, регистрирует этот объект, как получателя событий, и в примере выше, инициализирует графический вывод в окно на экране.
Предположим, мы хотим создать экземпляр Basic_Window , но с красным фоном. Обычно, чтобы изменить поведение класса, надо извлечь из него и переопределить соответствующие виртуальные методы. Мы пишем:

Class RedWindow: public Basic_Window {
virtual void handle_create_event() { set_background(RED); }
public:
RedWindow(Rect rect) : Basic_Window(Rect rect) {}
};
RedWindow red_window(default_rect);

Но red_window появится белым, а не красным! Чтобы создать RedWindow , родительский объект должен быть создан первым. После завершения Basic_Window::Basic_Window() , виртуальные таблицы RedWindow вступают в силу, метод handle_create_event() становится неприменимым, и конструктор RedWindow() выполняется. Конструктор Basic_Window() регистрирует объект графического инструментария, который мгновенно начинает посылать события объекту (например, CREATE-событие). Конструктор Basic_Window() еще не закончен (это не гарантировано), поэтому переопределенный виртуальный метод еще не на месте. Таким образом, CREATE-событие будет обрабатываться Basic_Window::handle_create_event() . Виртуальные таблицы RedWindow класса будут созданы лишь тогда, когда базовый класс полностью построен, то есть, когда окно уже на экране. Изменение цвета окна на данном этапе приведет к досадной ошибке.

Есть простой обходной путь: запретить каждому конструктору регистрировать объект графического инструментария. Обработка событий будет построена таким образом, чтобы сдержать окончание инициализации до производных классов. Очень заманчиво рассматривать виджеты на экране, как «лицо» объекта GUI приложения в памяти. Как показывает приведенный выше пример, эта связь между экраном и C++ объектом реализовать не так просто: они рождаются отдельно.

Нет синтаксических средств переключения событий

Предположим, что библиотека классов включает в себя графический интерфейс класса PictWindow , который отображает фотографию в окно:

Class PictWindow {
Picture picture;
public:
virtual void repaint() { gt_draw_pict(picture); }
...
};

Мы хотели бы наложить небольшой прямоугольник в определенной области изображения. С этой целью, мы можем попытаться создать подкласс PictWindow :


Rect rect;
virtual void repaint() { gt_draw_rect(rect); }
};

К сожалению, когда мы создадим экземпляр OvWindow , то увидим только прямоугольник в пустом окно, и никакого изображения. С того момента, как OvWindow::repaint() переопределяет PictWindow::repaint() , последняя функция не будет вызываться, когда окно должно быть отрисовано. Мы должны были реализовать OvWindow так:

Class OvWindow: public PictWindow {
Rect rect;
virtual void repaint() { PictWindow::repaint(); gt_draw_rect(rect); }
public:
OvWindow(void) : PictWindow() {}
};

Конструктор OvWindow изложен, чтобы подчеркнуть, что метод OvWindow::repaint() должен быть отложен до суперкласса, как делают конструкторы. В самом деле, конструктор производного объекта с начала вызывает конструктор корреспондирующего объекта. repaint() следует отложить его родитель: методу в базовом классе, который его переопределяет.

В итоге: Плохая совместимость C++ / GUI

C++ был разработан как «статический» язык:

  • с отслеживанием лексем
  • проверкой статических типов
  • со статическими иерархиями классов
  • без «сборки мусора»
  • с системой сообщений без определенных иерархий времени компиляции

GUI объекты:

  • характерны динамические объекты, а зачастую и единственные в своем роде
  • как правило, живут далеко за рамками, в которых они были созданы
  • иерархии определяются в значительной степени потоками событий и их расположением, а не наследованием классов
  • иерархии строятся и разрушаются во время выполнения, зачастую в ответ на непредсказуемые действия пользователя

C + + не предназначен для поддержки динамической защиты обмена сообщениями и передачами (кроме исключений). Все это приводит к дублированию графического инструментария и функциональности оконного менеджера, разрастанию кода, использованию небезопасных функций и отказ от многих сильных сторон C++.

Выводы

Конечно, все эти «коряги» не являются фатальными. C++ является универсальным и мощным языком и, следовательно, способен выразить все возможные алгоритмы расчета. Поэтому, если приложение требует динамических функций, таких как те, что есть в Tcl / Tk , Scheme / Tk , Postscript и подобных; используя C++, Вы всегда можете сделать что-то по их примеру. С другой стороны, почему бы не использовать язык, где все эти черты присутствуют?

C++ - один из самых мощных и востребованных языков программирования. Ежедневно на нём пишут сотни приложений, зачастую использующих GUI. Однако работа с графикой не всегда удобна программисту - в таком случае применяют готовые графические библиотеки. Они позволят сделать разработку графической части приложений максимально быстрой и удобной.

SFML

Qt

Кроссплатформенная библиотека Cocos2D-X призванна упростить разработку мобильных игр. Поддерживает все те же платформы, что и Qt. Из плюсов стоит отметить доступность, удобство эксплуатации и создание отдельного конструктора игр, основанного на библиотеке Cocos Creator . В списке игр, основанных на движке, есть всемирно известная BADLAND, работающая на всех доступных платформах.

Кое-что ещё

Если при создании игры вам нужно работать с графикой и анимацией в больших объёмах, то лучше использовать Unity вместо Cocos2D-X. В Unity имеется возможность плавной интеграции с такими инструментами, как Photoshop, Maya или Blender. В Cocos2D-X вся графика добавляется извне и на неё ссылаются из кода.

В Рунете нет уроков по этой библиотеке, но на английском языке есть отличный курс от разработчиков.

Juce

Пожалуй, одна из самых известных графических библиотек. GTK+ - графический фреймворк, широко применямый во многих системах. Изначально он задумывался как компонент GIMP, но за 20 лет после выпуска первой стабильной версии он нашёл применение в сотнях других приложений.

Сейчас GTK+ - полноценный графический фреймворк, не уступающий тому же QT. Он поддерживает разные языки программирования и продолжает развиваться.

Кое-что ещё

В своё время библиотека создавалась в качестве альтернативы Qt, которая была платной. GTK+ - один из немногих фреймворков, которые поддерживают язык C. Библиотека кроссплатформенная, но есть мнение , что программы на Linux выглядят более нативно, чем на Windows или Mac (GTK+ хорошо поддерживается даже на KDE). Интересно, что из-за некоторых проблем с кроссплатформенностью Wireshark перешла на Qt.

Пример первой программы можно посмотреть на Википедии .

Другие интересные статьи по C++ можно посмотреть у нас .

Заключение

Выше представлены наиболее популярные технологии для работы с GUI не только на C++, но иногда и на других языках (например, Qt и GTK+). Однако всегда следует учитывать особенности той или иной технологии. Выпишите список функций своего приложения, ещё раз прочитайте описания всех библиотек и фреймворков, и только после этого выбирайте то, что действительно подходит больше всего для проекта.

Министерство образования и науки Российской Федерации

Федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования

«УФИМСКИЙ ГОСУДАРСТВЕННЫЙ НЕФТЯНОЙ

ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»

Кафедра вычислительной техники и инженерной кибернетики

Создание приложения c графическим интерфейсом пользователя в среде microsoft visual studio 2010

Учебно-методическое пособие

для проведения лабораторных и практических занятий

со студентами направления

230100 (09.03.01) «Информатика и вычислительная техника»

В учебно-методическом пособии приведены теоретические сведения, задания для практических и лабораторных работ курса «Программирование».

Пособие адресовано преподавателям дисциплины, а так же студентам направления: 230100 «Информатика и вычислительная техника».

Составители: Габдуллина А.А., ст. преподаватель каф. ВТИК

Дружинская Е.В., ст. преподаватель каф. ВТИК

Рецензент: Филиппов В.Н., к.т.н., доцент каф. ВТИК.

1.Теоретические сведения 4

1.1. Основные понятия 4

1.2. Знакомство с приложением Windows Form в Microsoft Visual Studio 2010 4

1.3. Элемент управления Form 7

1.5. Функция MessageBox 9

1.6. Элемент управления TextBox 10

2.Практическое задание. Знакомство с приложением Windows Form в Microsoft Visual Studio 2010 12

2.1. Структура оценивания выполненной работы 12

2.2. Порядок выполнения практической работы 12

3.Лабораторная работа. Разработка приложений в среде Microsoft Visual Studio 2010 16

3.1. Порядок выполнения лабораторной работы 16

3.2. Задание 1. Табулирование функции и вычисление её значений в указанном интервале с заданным шагом 16

3.3. Индивидуальные задания 19

3.4. Задание 2. Обработка двумерных массивов 21

3.5. Индивидуальные задания 27

  1. Теоретические сведения

  1. 1.1. Основные понятия

Автоматизация информационных процессов в настоящее время представляется, в первую очередь, разработкой программного приложения с графическим интерфейсом пользователя (GUI), управляющего потоками данных.

Графический интерфейс пользователя (Graphical User Interface, GUI) это система средств для взаимодействия пользователя с устройством, основанная на представлении всех доступных пользователю системных объектов и функций в виде графических компонентов экрана (окон, кнопок, полос прокрутки и т. п.).

Чаще всего элементы интерфейса в GUI реализованы на основе метафор и отображают их назначение и свойства, что облегчает понимание и освоение программ неподготовленными пользователями. Таким образом, работа пользователя осуществляется с экранными формами, содержащими объекты управления и панели инструментов с кнопками действий для обработки.

Стандартный графический интерфейс пользователя должен отвечать ряду требований:

Поддерживать информационную технологию работы пользователя с программным продуктом;

Ориентироваться на конечного пользователя, который общается с программой на внешнем уровне взаимодействия;

Удовлетворять принципу «шести», когда в одну линейку меню включают не более 6 понятий, каждое из которых содержит не более 6 опций;

    сохранять стандартизованное назначение графических объектов и, по возможности, их местоположение на экране.

В объектно-ориентированном программировании мы имеем дело с классами и объектами. Объекты – это составные типы данных: они объединяют несколько значений в единый модуль и позволяют нам записывать и сохранять эти значения по имени. Другими словами, объект – это неупорядоченная коллекция свойств, каждое из которых имеет имя и значение. Именованные значения, содержащиеся в объекте, могут быть как элементарными типами, например числами или строками, так и другими объектами.

При разработке не консольных приложений, основным понятием является Форма.

Форма – это контейнер для размещения элементов управления среды разработки.

Свойства – возможность получения доступа к информации, которая хранится в этом элементе.

Методами называют набор действий, которые может совершать объект.

Событие – действие, распознаваемое объектом (например, щелчок мышью, нажатие клавиши), для которого можно запрограммировать отклик, т.е. реакцию объекта на произошедшее событие.

Лучшие статьи по теме