1.61M
Категория: ПрограммированиеПрограммирование

Сигналы-слоты. Элементы управления

1.

Сигналы-слоты. Элементы управления
1

2.

Сигнал
Это методы, которые могут выполнять пересылку сообщений
Причина появления сигнала – изменение состояния управляющего
элемента
Присоединенный объект, получив сигнал, МОЖЕТ на него отреагировать.
Сигнал определяется в классе как метод, только без реализации
Методы сигналов ничего не возвращают и имеют тип void
Сигнал не обязан соединяться со слотом
Библиотека предоставляет большой набор уже готовых сигналов для
существующих элементов управления

3.

Слот
Это методы, которые присоединяются к сигналам
Слоты определяются в классе как public, private, protected
В объявлении группы слотов должно стоять
private slots, protected slots, public slots
В библиотеке есть целый ряд уже реализованных слотов
Слоты могут быть виртуальными

4.

Слоты – сигналы
Соединение сигнала и слота выполняет метод
Object :: connect ( const QObject * sender, const char*
SIGNAL( method()) ,
const QObject* receiver,
Qt:: ConnectionType type= Qt:: AutoConnection);
const char* SLOT(method()) ,
type:
Qt:: DirectConnection
Qt:: QueuedConnection
Qt::AutoConnection

5.

Пример 1( основная программа main.cpp)
#include< QtWidgets>
#include «Counter.h»
int main (int argc, char ** argv)
{
QApplication app(argc, argv);
QLabel lbl(«0»);
QPushButton cmd( «ADD»);
Counter counter;
lbl.show();
cmd.show();

6.

Пример 1( основная программа main.cpp)
QObject :: connect (&cmd, SIGNAL(clicked()), & counter,
SLOT(slotInc()));
QObject :: connect (&counter, SIGNAL(counterChanged( int)),
& lbl, SLOT(setNum(int)));
QObject :: connect (&counter, SIGNAL(goodbye()), &app ,
SLOT(quit()));
return app.exec();
}

7.

Counter.h
# pragma once
#include<QObject>
class Counter : public QObject {
Q_OBJECT
private : int m_nValue;
public: Counter();
public slots: void slotInc();
signals:
void goodbye();
void counterChanged( int);
};

8.

Counter.cpp
# include «Counter.h»
Counter :: Counter() :QObject(), m_nValue(0)
{
}
void Counter :: slotInc()
{
emit counterChanged(++m_nValue);
if (m_nValue == 5) emit goodbye();
}

9.

ЗАМЕЧАНИЯ
Следите за совпадением типов сигналов со слотами!
connect (obj1, SIGNAL(sig ( int)), obj2, SLOT(slt (int)));
connect (obj1, SIGNAL(sig ( int)), obj2, SLOT(slt (QString)));
Можно игнорировать в слоте значения, переданные сигналом!
connect (obj1, SIGNAL(sig ( int)), obj2, SLOT(slt ()));
connect (obj1, SIGNAL(sig ( )), obj2, SLOT(slt (int)));
Не указывайте вместе с типом имя переменной!
connect (obj1, SIGNAL(sig ( int n)), obj2, SLOT(slt (int n)));

10.

Разъединение объектов
При уничтожении объекта все, связанные с ним соединения,
уничтожаются АВТОМАТИЧЕСКИ
QObject:: disconnect ( sender, signal, receiver, slot);
void main()
{…
QObject:: disconnect ( pSender, SIGNAL(signalMethod()),
pReceiver, SLOT(slotMethod()));
}

11.

Переопределение сигналов
QSignalMapper
Можно переопределить сигналы
Сделать так, чтобы в слот отправлялись значения типов int,
QString или QWidget

12.

Предположим, что
В программе есть 2 кнопки : при нажатии на кнопку 1 нужно
отобразить сообщение Button1Action, а при нажатии на
кнопку 2 – сообщение Button2Action
РЕШЕНИЕ
Создать в классе 2 разных слота, соединить их с сигналами
clicked() от каждой из двух кнопок и выводить каждый свое
сообщение

13.


MyClass :: MyClass (QWidget * pwgt)
{ ….
QSignalMapper *psigMapper = new QSignalMapper(this);
connect ( psigMapper, SIGNAL( mapped( const QString &)), this ,
SLOT (slotShowAction ( const QString &)));
QPushButton *pcmd1= new QPushButton («Button1»);
connect (pcmd1, SIGNAL( clicked()), psigMapper, SLOT(map)));
psigMapper - > setMapping (pcmd1, «Button1 Action»);

14.


QPushButton *pcmd2= new QPushButton («Button2»);
connect (pcmd2, SIGNAL( clicked()), psigMapper,
SLOT(map)));
psigMapper - > setMapping (pcmd2, «Button2 Action»);
…..
}
void MyClass :: slotShowAction (const QString str)
{
qDebug() < < str; }

15.

Иерархии объектов
QObject (QObject * pobj=0);
Указатель на объект- предок
setParent(); setObjectName(); objectName()

16.

Иерархии объектов
QObject *pobj1= new Object;
QObject *pobj2= new Object (pobj1));
QObject *pobj3= new Object (pobj1));
QObject *pobj4= new Object (pobj2));
pobj2- > setObjectName(„the first child of pobj1“);
pobj3- > setObjectName(„the second child of pobj1“);
pobj4- > setObjectName(„the first child of pobj2“);

17.


for ( QObject *pobj = pobj4; pobj; pobj = pobj - > parent())
{qDebug() < < pobj - > objectName(); }
pobj 1
parent(); children();
pobj2- > parent();
pobj1- > children();
pobj2
pobj4
pobj 3

18.


QObject *pobj= pobj1- > findChild <QObject *>( « the first child of
pobj2»);
QList< QObject*> pList=pobjl- > findChildren< QObject *>( QRegExp
(„th*“));
QList< QObject*> pList=pobjl- > findChildren< QObject *>( QRegExp
());

19.

dumpObjectInfo(), dumpObjectTree()
Имя объекта
Класс, от которого создан объект
Сигнально-слотовые отношения
stdout

20.

ЗАМЕЧАНИЕ
Все объекты должны создаваться в памяти ДИНАМИЧЕСКИ!
new

21.

Метаобъектная информация (QMetaObject)
QObject:: metaObject();
qDebug() < < pobj1 - > metaObject ()- > className();
if(pobj1 - > metaObject ()→ className () = = „ MyClass“)
{ // действия }
if(pobj1 - > inherits („QWidget“)
{ QWidget * pwgt= static_cast<QWidget *> (pobj);
// действия c pwgt }

22.

Рекомендации для проекта с QT
Файлы классов лучше разбивать на 2 части : часть определения
класса помещается в *.h, а реализация класса – *. cpp, основная
программа – main.cpp
В заголовочном файле с определением класса должна быть
директива #ifndef
#ifndef _MyClass_h_
#pragma once
#define _MyClass_h_
class MyClass {
….};
class MyClass
{
….
};
#endif

23.

Рекомендации
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass();
….
}

24.

Структура qt-проекта
Файлы исходного кода: file.h, file.cpp
Файл проекта : file.pro
Файлы ресурсов: file. qrc
make-файл, созданный утилитой qmake и содержащий:
все необходимые инструкции для создания готового исполняемого модуля;
вызов MOC для создания дополнительного кода C++ и необходимых
заголовочных файлов;
если проект содержит qrc-файл, то будет создан файл C++, содержащий
данные ресурсов.
После этого все исходные файлы компилируются C++-компилятором в
файлы объектного кода, которые объединяются компоновщиком link в
готовый исполняемый модуль.

25.

Структура qt-проекта
Схема
создания
исполняемого
модуля

26.

Информация о библиотеке qt
QLibraryInfo
#include<QtCore>
Int main( int argc, char** argv)
{ qDebug() < < « License Products:» < <QLibraryInfo::
licensedProducts();
qDebug() < < » Examples» < < QLibraryInfo:: location
(QLibraryInfo:: ExamplesPath);
}

27.

qDebug(), qWarning(), qFatal()
<QtGlobal.h>
Microsoft Visual Studio – окно отладчика
OC Linux – стандартный поток вывода ошибок
qFatal () – после вывода сообщения сразу завершает работу
приложения

28.

Элементы управления
28

29.

30.

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

31.

QWidget
254 метода, 53 свойства
Может служить контейнером для других виджетов
Виджеты без предков (виджеты верхнего уровня) имеют собственное
окно
setGeometry(), show(), hide()
QWidget ( QWidget * pwgt=0, Qt:: WindowFlags f=0)
wgt. setWindowFlags( Qt::WindowTitleHint | Qt:: WindowStaysOnTopHint);
wgt. setWindowTitle( «My window»);
setEnabled()

32.

33.

Размер и координаты виджета
x()
X
О
ВИДЖЕТ
width()
Y
height()
y()

34.

Размер виджета
size(), height(), width()
x(), y(), pos()
geometry()
pwgt - > move( 5,5);
pwgt - > resize( 260, 330);
pwgt - > setGeometry( 5,5, 260,330);

35.

Механизм закулисного хранения
Технология закулисного хранения ( Backing Store)
заключается в запоминании в памяти компьютера растровых
изображений для всех виджетов окна в любое время,
Что позволяет быстро помещать нужную часть хранимой
области без вызова системой событий рисования (paint event)

36.

Установка фона виджета
Фон может быть цветом или растровым изображением.
Для заполнения цветом сначала создаем объект палитры,
затем устанавливаем его в виджете setPalette()
Потомки виджета по умолчанию не заполняются фоном.
wgt. setAutoFillBackground( true);

37.

Файл main.cpp
#include< QtWidgets>
// <QtGui>
int main(int argc, char** argv)
{ QApplication app(argc, argv);
QWidget wgt; QWidget * pwgt1 = new QWidget(&wgt);
QPalette pal1;
pal1.setColor(pwgt1->backgroundRole(), Qt::blue);
pwgt1- > setPalette(pal1); pwgt1->resize(100, 100); pwgt1->move(25, 25);
pwgt1->setAutoFillBackground(true);
QWidget* pwgt2 = new QWidget(&wgt);
QPalette pal2; pal2.setBrush(pwgt2->backgroundRole(), QBrush(QPixmap("stone.jpg")));
pwgt2→setPalette(pal2);
pwgt2->setAutoFillBackground(true);
wgt.resize(200, 200);
wgt.show(); return app.exec(); }
pwgt2->resize(100, 100); pwgt2->move(75, 75);

38.

Изменение указателя мыши
QCursor <QCursor>
setCursor()
pos(), setPos()
QBitmap
QPixmap

39.

40.

41.

42.

Рамки
QFrame : public QWidget
setFrameStyle()
Флаги теней: QFrame: Raised, QFrame:: Plain, QFrame::
Sunken
setContentMargin()
QFrame pfrm= new QFrame;
pfrm - > setFrameStyle (QFrame:: Box | QFrame :: Sunken);
pfrm - > setLineWidth( 3);

43.

44.

QStackedWidget (стек виджетов)
Класс показывает в отдельно взятый промежуток времени
только одного из потомков.
Используют тогда, когда есть много виджетов и нужно, чтобы
только один из них в определенное время был видимым.
QStackedWidget : QFrame
addWidget()
removeWidget()
setCurrentWidget( указатель_на_виджет)
setCurrentIndex(идентификатор_виджета)
indexOf( указатель_на_виджет)

45.

Виджет видовой прокрутки
Представляет окно для просмотра только части информации.
Применяется для отображения информации, размеры
которой превышают выделенную для нее область просмотра
Является совокупностью нескольких виджетов, работающих
вместе
QScrollArea : QFrame

46.

47.

48.

Виджет видовой прокрутки
Может размещать виджеты потомков
QScrollArea sa;
sa. setHorisontalScrollBarPolicy (Qt:: ScrollBarAlways);
sa. setVerticalScrollBarPolicy( Qt:: ScrollBarAlways);
setWidget(указатель_на_виджет)
widget()
removeChild()
setFixedSize()

49.

Управление автоматическим размещением элементов
Классы компоновки виджетов (Layouts) – контейнеры,
которые после изменения размеров окна автоматически
приводят в соответствие размеры и координаты виджетов,
находящихся в нем.
Компоновка определяет расположение различных виджетов
друг относительно друга .
Qt предоставляет менеджеры компоновки, позволяющие
организовать размещение виджетов на поверхности другого
виджета.

50.

Layout managers
QLayout ---класс, унаследованный от QObject, QLayoutItem
<QLayout>
QGridLayout управляет табличным
размещением
QHBoxLayout , QVBoxLayout
– для горизонтального и
вертикального размещения

51.


setSpacing( pixels)
setContentsMargins() – left, right, top, bottom

52.


addWidget () – добавляет виджеты в компоновку
addLayout() – добавляет встроенные методы компоновки
removeWidget() – удаляет виджет из компоновки

53.

Горизонтальное или вертикальное размещение
Классы
QBoxLayout
QHBoxLayout
QVBoxLayout

54.

QBoxLayout
Параметры конструктора:
LeftToRight
RightToLeft
TopToBottom
BottomToTop
Методы:
insertWidget(), insertLayout(), insertSpacing(), insertStretch()

55.

56.

Фактор растяжения
addStretch()

57.

58.

QHBoxLayout

59.

60.

QVBoxLayout

61.

Вложенные размещения

62.

63.

Табличное размещение QGridLayout
pLayout - > addWidget (widget, 17, 1, Qt:: AlignCenter);

64.

65.

66.

67.

68.

69.

70.

71.

72.

73.

Порядок следования табулятора
QWidget:: setTabOrder()
QWidget:: setTabOrder( A, B);
QWidget:: setTabOrder( B,C);

74.

Разделители QSplitter
QSplitter
setOpaqueResize(true);
English     Русский Правила