Похожие презентации:
Разработка приложений с GUI
1.
Основы проектированияпрограммного обеспечения
Тема 3: Разработка приложений с GUI
ст. преп. каф. ВТ
Васильев В.С.
2.
Опрос1. Какие есть варианты создания графического интерфейса в
различных языках программирования?
2. Какие проблемы решают фреймворки?
2
3.
int API.WINAPI
WinMain
(
1.1 Windows
Hello
World
HINSTANCE hInst,
HINSTANCE hPrevInstance,
LPSTR cmdline,
int nCmdShow
) {/*…*/}
Создается сообщение и консоль
• hInst - дескриптор для данного экземпляра
программы;
• cmdline - командная строка;
• hPrevInstance – дескриптор предыдущего
экземпляра. В 16х позволял скопировать
данные предыдущего экземпляра этого же
приложения чтобы быстрее запуститься и
(при необходимости) взаимодействовать с
ним.
Из MSDN: “This parameter is always NULL. If you
need to detect whether another instance already
exists, create a uniquely named mutex using the
CreateMutex function”.
• nCmdShow - Определяет, как окно должно
быть показано: SW_HIDE, SW_MAXIMIZE,
SW_MINIMIZE,
SW_SHOWMAXIMIZED, SW_SHOWNA, …
3
4.
1.2 Windows API. Полезные типы данных.Некоторые префиксы венгерской нотации
Префикс Значение
hDC
handle (указатель на контекст
устройства)
I
целое (integer)
L
длинный тип (long)
Lp
длинный указатель
Lpsz
указатель на строку,
заканчивающуюся нулевым
байтом
m_
переменная класса
N
short или int
P
указатель
Pfn
указатель на функцию
Pst
указатель на структуру
Psz
указатель на строку,
заканчивающуюся нулевым
байтом
Pv
указатель на тип void
S
строка
Sz
строка, заканчивающая нульсимволом
U
беззнаковый символ
Тип
Описание
HANDLE определяет идентификатор; 32-разрядное
целое, используемое в качестве дескриптора –
числа, определяющего некоторый ресурс
HWND
HDC
определяет идентификатор окна
определяет идентификатор контекста
устройства
LONG
LPSTR
NULL
UINT
32-битовое целое со знаком
Указатель (линейный)
0
Беззнаковый целый (32 бита для Win32)
WCHAR 16-битовый символ UNICODE. Используется
для представления символов языков мира
4
5.
1.2 Windows API. Обработка сообщенийGetMessage не отдает
управление программе, пока не
придет какое-либо сообщение.
DispatchMessage, определяет
предназначенное этому
сообщению окно и вызывает
соответствующую процедуру
обработки событий.
BOOL WINAPI GetMessag
e(
_Out_
LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_
n,
LRESULT DefWindowProc(
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
_In_
) ; // Передает обработку «ненужного сообщения» ОС
ax
);
UINT wMsgFilterMi
UINT wMsgFilterM
5
6.
1.2 Windows API. Более интересныйобработчик сообщений
6
7.
1.3 Windows API. Класс окнаОкно имеет: хэндл, заголовок, обработчик сообщений, стиль (сложная комбинация
флагов), цвет фона, вид курсора, …
7
8.
103#define
1001
#define
1004
#define
1005
#define
1005
#define
1006
#define
1007
#define
1008
#define
1009
#define
1010
#define
1011
#define
1012
#define
1013
#define
1014
#define
1015
#define
1016
IDC_EDIT1
IDC_Continue
IDC_Break
1.4 Windows API. Ресурсы
// resources.rc:
IDC_N1
IDC_S1
IDC_C1
IDC_N2
IDC_S2
IDC_C2
IDC_N3
IDC_S3
IDC_C3
IDC_N4
IDC_S4
IDC_C4
8
9.
1.5 Windows API. Некоторые проблемыи типичные ошибки
1. сложно структурировать код:
1.1 цикл обработки событий глобальный;
1.2 функция диспетчеризации вызовет
обработчик окна, но для этого все
обработчики надо зарегистрировать (в
одной точке?);
1.3 каждому ресурсу (строке, текстовому
полю, …) надо дать идентификатор,
причем, - уникальный в программе;
2. функции Win API имеют много
параметров;
3. многие параметры принимают int (в
качестве идентификатора) – проверка
типов отсутствует.
4. рисование внутри обработчика
WM_PAINT;
5. есть проекты типа MFC.
9
10.
2 Qt (в контексте разработки GUI)1. ОО-Фреймворк;
2. локализует ресурсы;
3. реализует механизм передачи сообщения нужному
объекту;
4. «рисование» перенесено в виртуальную функцию;
5. предоставляет механизм сигналов и слотов (чем
сигналы отличаются от событий?);
6. предоставляет дополнительный механизм для
сборки мусора;
7. реализует стили по умолчанию, которые можно
менять при необходимости (нет лишних
параметров);
8. менять стили можно с использованием QSS;
9. предоставляет механизм свойств (Properties);
10.поддерживает механизм раскладок
(компоновщиков);
10
11.имеет среду разработки GUI мышкой;
11.
2.1 Qt. Сборка мусораint main() {
Animal* a = new Animal();
Animal* b = new Animal(a);
Animal* c = new Animal(a);
delete a;
/*
A
/\
B C
*/
}
11
12.
2.1 Qt. Сборка мусораclass SuperBase {
SuperBase *m_parent;
public:
SuperBase(SuperBase* parent = nullptr) {
m_parent = parent_;
}
virtual ~SuperBase() {
//???
}
};
class Animal : public SuperBase {
public:
Animal(SuperBase* parent = nullptr) : SuperBase(parent) {
}
};
12
13.
2.1 Qt. Сборка мусораclass SuperBase {
SuperBase *m_parent;
vector<SuperBase*> m_children;
public:
SuperBase(SuperBase* parent = nullptr) {
m_parent = parent;
if (m_parent)
m_parent->add_child(this);
}
void add_child(SuperBase* child) {
m_children.push_back(child);
}
https://onlinegdb.com/rktK4EfYD
virtual ~SuperBase() {
for (auto* child : m_children) {
delete child;
}
cout << "~";
}
};
13
14.
2.1 Qt. Сборка мусораstruct Time : public SuperBase {
Time(SuperBase* parent = nullptr) : SuperBase(parent) {
}
};
struct Widget : public SuperBase {
Widget(SuperBase* parent = nullptr) : SuperBase(parent) {
}
};
struct ClockWidget : public Widget {
Time* m_time;
ClockWidget(SuperBase* parent = nullptr) : Widget(parent) {
m_time = new Time(this);
}
};
int main() {
ClockWidget clock;
}
https://onlinegdb.com/HJDRrEzKP
14
15.
2.2 Qt. Виджеты и событияclass RunLine : public QLabel {
Q_OBJECT
public:
RunLine(QWidget *parent = 0);
public slots:
void setString(const QString string);
void setSpeed(const int speed);
protected:
virtual void timerEvent(QTimerEvent*);
int m_shift, m_timerId;
QString m_string;
};
https://pro-prof.com/archives/619
15
16.
2.2 Qt. Виджеты и событияvoid RunLine::timerEvent(QTimerEvent *) {
const int length = m_string.length();
if(++m_shift >= length)
m_shift = 0;
setText(m_string.right(m_shift) + m_string.left(length - m_shift));
}
void RunLine::setSpeed(const int speed) {
if (m_timerId)
killTimer(m_timerId);
m_timerId = 0;
if (speed < 0)
return;
if (speed)
m_timerId = startTimer(1000/speed);
}
void RunLine::setString(const QString string) {
m_string = string;
m_shift = 0;
setText(m_string);
}
https://pro-prof.com/archives/619
16
17.
2.3 Qt. Раскладки. Сигналы и слотыMainWidget::MainWidget(QWidget *parent) : QWidget(parent) {
QGridLayout *layout(new QGridLayout(this));
QSpinBox *speedSpinbox(new QSpinBox(this));
QLineEdit *textLine(new QLineEdit(this));
RunLine *runline(new RunLine(this));
// ...
}
https://pro-prof.com/archives/619
17
18.
2.3 Qt. Раскладки. Сигналы и слотыMainWidget::MainWidget(QWidget *parent) : QWidget(parent) {
QGridLayout *layout(new QGridLayout(this));
QSpinBox *speedSpinbox(new QSpinBox(this));
QLineEdit *textLine(new QLineEdit(this));
RunLine *runline(new RunLine(this));
layout->addWidget(textLine, 1, 1, 1, 1);
layout->addWidget(speedSpinbox, 1, 2, 1, 1);
layout->addWidget(runline, 2, 1, 1, 2);
}
https://pro-prof.com/archives/619
18
19.
2.3 Qt. Раскладки. Сигналы и слотыMainWidget::MainWidget(QWidget *parent) : QWidget(parent) {
QGridLayout *layout(new QGridLayout(this));
QSpinBox *speedSpinbox(new QSpinBox(this));
QLineEdit *textLine(new QLineEdit(this));
RunLine *runline(new RunLine(this));
layout->addWidget(textLine, 1, 1, 1, 1);
layout->addWidget(speedSpinbox, 1, 2, 1, 1);
layout->addWidget(runline, 2, 1, 1, 2);
connect(speedSpinbox, SIGNAL(valueChanged(int)), runline, SLOT(setSpeed(int)));
connect(textLine, SIGNAL(textChanged(QString)), runline, SLOT(setString(QString)));
}
https://pro-prof.com/archives/619
19
20.
2.4 Qt. Использование QtDesignernamespace Ui {
class MainUI;
}
class MainDialog :public QDialog {
Q_OBJECT
public:
explicit MainDialog(QWidget *parent = 0);
~MainDialog();
public slots:
private:
Ui::MainUI *m_ui;
};
https://pro-prof.com/archives/958
20
21.
2.4 Qt. Использование QtDesignerhttps://pro-prof.com/archives/958
MainDialog::MainDialog(QWidget *parent)
: QDialog(parent), m_ui(new Ui::MainUI) {
m_ui->setupUi(this);
m_ui->m_counter->set(6, 200);
connect(m_ui->m_start, SIGNAL(clicked()), m_ui->m_counter, SLOT(on_start()));
connect(m_ui->m_stop, SIGNAL(clicked()), m_ui->m_counter, SLOT(on_stop()));
}
MainDialog::~MainDialog() {
delete m_ui;
}
21