Главная страница

ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов


Скачать 7.92 Mb.
НазваниеНиколай Прохоренок Владимир Дронов
Дата05.05.2023
Размер7.92 Mb.
Формат файлаpdf
Имя файлаПрохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен.pdf
ТипДокументы
#1111379
страница39 из 83
1   ...   35   36   37   38   39   40   41   42   ...   83
")
 text()
— возвращает текстовое представление введенного символа в кодировке Unicode или пустую строку, если была нажата специальная клавиша;
 modifiers()
— позволяет определить, какие клавиши-модификаторы (, ,
и др.) были нажаты вместе с клавишей. Может содержать значения следующих атрибутов из класса
QtCore.Qt или их комбинацию:

NoModifier
— модификаторы не были нажаты;

ShiftModifier
— была нажата клавиша ;

ControlModifier
— была нажата клавиша ;

AltModifier
— была нажата клавиша ;

MetaModifier
— была нажата клавиша ;

KeypadModifier
— была нажата любая клавиша на дополнительной клавиатуре;

GroupSwitchModifier
— была нажата клавиша (только в X11).
Вот пример определения, была ли нажата клавиша-модификатор : if e.modifiers() & QtCore.Qt.ShiftModifier: print("Нажата клавиша-модификатор ")
 isAutoRepeat()
— возвращает
True
, если событие было вызвано удержанием клавиши нажатой, и
False
— в противном случае;
 matches()
— возвращает значение
True
, если была нажата специальная комбинация клавиш, соответствующая указанному значению, и
False
— в противном случае. В качестве значения указываются атрибуты из класса
QKeySequence
— например,
QKeySequence.Copy для комбинации клавиш + (Ко- пировать):

420
Часть II. Библиотека PyQt 5 if e.matches(QtGui.QKeySequence.Copy): print("Нажата комбинация +")
Полный список атрибутов содержится в документации по классу
QKeySequence
(см. https:// doc.qt.io/qt-5/qkeysequence.html#StandardKey-enum).
При обработке нажатия клавиш следует учитывать, что:
 компонент должен иметь возможность принимать фокус ввода. Некоторые компоненты по умолчанию не могут принимать фокус ввода — например, надпись. Чтобы изменить способ получения фокуса, следует воспользоваться методом setFocusPolicy(<Способ>)
, который мы рассматривали в разд. 19.8.1;
 чтобы захватить эксклюзивный ввод с клавиатуры, следует воспользоваться методом grabKeyboard()
, а чтобы освободить ввод — методом releaseKeyboard()
;
 можно перехватить нажатие любых клавиш, кроме клавиши и комбинации
+. Эти клавиши используются для передачи фокуса следующему и преды- дущему компоненту соответственно. Перехватить нажатие этих клавиш можно только в методе event(self, )
;
 если событие обработано, следует вызвать метод accept()
объекта события. Чтобы родительский компонент смог получить событие, вместо метода accept()
необходимо вызвать метод ignore()
19.9. События мыши
События мыши обрабатываются не реже, чем события клавиатуры. С помощью специаль- ных методов можно обработать нажатие и отпускание кнопки мыши, перемещение указате- ля, вхождение указателя в область компонента и выхода из этой области. В зависимости от ситуации можно изменить вид указателя — например, при выполнении длительной опера- ции отобразить указатель в виде песочных часов. В этом разделе мы рассмотрим изменение вида указателя мыши как для отдельного компонента, так и для всего приложения.
19.9.1. Нажатие и отпускание кнопки мыши
При нажатии и отпускании кнопки мыши вызываются следующие методы:
 mousePressEvent(self, )
— вызывается при нажатии кнопки мыши;
 mouseReleaseEvent(self, )
— вызывается при отпускании ранее нажатой кнопки мыши;
 mouseDoubleClickEvent(self, )
— вызывается при двойном щелчке мышью в области компонента. Следует учитывать, что двойному щелчку предшествуют другие события. Последовательность событий при двойном щелчке выглядит так:
MouseButtonPress
MouseButtonRelease
MouseButtonDblClick
MouseButtonPress
MouseButtonRelease
Задать интервал двойного щелчка позволяет метод setDoubleClickInterval()
класса
QApplication
, а получить его текущее значение — метод doubleClickInterval()
того же класса.

Глава 19. Обработка сигналов и событий
421
Через параметр

доступен экземпляр класса
QMouseEvent
, хранящий дополнительную информацию о событии. Он поддерживает такие методы:
 x()
и y()
— возвращают координаты по осям
X
и
Y
соответственно в пределах области компонента;
 pos()
— возвращает экземпляр класса
QPoint с целочисленными координатами в преде- лах области компонента;
 localPos()
— возвращает экземпляр класса
QPointF
с вещественными координатами в пределах области компонента;
 globalX()
и globalY()
— возвращают координаты по осям
X
и
Y
соответственно в преде- лах экрана;
 globalPos()
— возвращает экземпляр класса
QPoint с координатами в пределах экрана;
 windowPos()
— возвращает экземпляр класса
QPointF
с вещественными координатами в пределах окна;
 screenPos()
— возвращает экземпляр класса
QPointF
с вещественными координатами в пределах экрана;
 button()
— позволяет определить, щелчок какой кнопкой мыши вызвал событие. Воз- вращает значение одного из следующих атрибутов класса
QtCore.Qt
(здесь указаны не все атрибуты, полный их список приведен на странице https://doc.qt.io/qt-5/qt.html#
MouseButton-enum):

NoButton

0
— кнопки не нажаты. Это значение возвращается методом button()
при перемещении указателя мыши;

LeftButton

1
— нажата левая кнопка мыши;

RightButton

2
— нажата правая кнопка мыши;

MidButton и
MiddleButton

4
— нажата средняя кнопка мыши;

XButton1
,
ExtraButton1
и
BackButton

8
— нажата первая из дополнительных кно- пок мыши;

XButton2
,
ExtraButton2
и
ForwardButton

16
— нажата вторая из дополнительных кнопок мыши;
 buttons()
— позволяет определить все кнопки, которые нажаты одновременно. Возвра- щает комбинацию упомянутых ранее атрибутов. Вот пример определения нажатой кнопки мыши: if e.buttons() & QtCore.Qt.LeftButton: print("Нажата левая кнопка мыши")
 modifiers()
— позволяет определить, какие клавиши-модификаторы (, ,
и др.) были нажаты вместе с кнопкой мыши. Возможные значения мы уже рас- сматривали в разд. 19.8.3;
 timestamp()
— возвращает в виде числа отметку системного времени, в которое возник- ло событие.
Если событие было успешно обработано, следует вызвать метод accept()
объекта события.
Чтобы родительский компонент мог получить событие, вместо метода accept()
нужно вы- звать метод ignore()

422
Часть II. Библиотека PyQt 5
Если у компонента атрибут
WA_NoMousePropagation класса
QtCore.Qt установлен в
True
, со- бытие мыши не будет передаваться родительскому компоненту. Значение атрибута можно изменить с помощью метода setAttribute()
, вызванного у этого компонента: button.setAttribute(QtCore.Qt.WA_NoMousePropagation, True)
По умолчанию событие мыши перехватывает компонент, над которым был произведен щелчок мышью. Чтобы перехватывать нажатие и отпускание мыши вне компонента, следу- ет захватить мышь вызовом метода grabMouse()
. Освободить захваченную ранее мышь по- зволяет метод releaseMouse()
19.9.2. Перемещение указателя мыши
Чтобы обработать перемещение указателя мыши, необходимо переопределить метод mouseMoveEvent(self, )
. Через параметр

доступен экземпляр класса
QMouseEvent
, содержащий дополнительную информацию о событии. Методы этого класса мы уже рассматривали в предыдущем разделе. Следует учитывать, что метод button()
при перемещении мыши возвращает значение
QtCore.Qt.NoButton
По умолчанию метод mouseMoveEvent()
вызывается только в том случае, если при переме- щении удерживается нажатой какая-либо кнопка мыши. Это сделано специально, чтобы не создавать лишних событий при обычном перемещении указателя мыши. Если необходимо обрабатывать любые перемещения указателя в пределах компонента, следует вызвать у это- го компонента метод setMouseTracking()
, которому передать значение
True
. Чтобы обрабо- тать все перемещения внутри окна, нужно дополнительно захватить мышь вызовом метода grabMouse()
Метод pos()
объекта события возвращает позицию точки в системе координат текущего компонента. Чтобы преобразовать координаты точки в систему координат родительского компонента или в глобальную систему координат, нужно воспользоваться следующими методами класса
QWidget
:
 mapToGlobal()
— преобразует координаты точки из системы координат компо- нента в глобальную систему координат. Возвращает экземпляр класса
QPoint
;
 mapFromGlobal()
— преобразует координаты точки из глобальной в систему координат компонента. Возвращает экземпляр класса
QPoint
;
 mapToParent()
— преобразует координаты точки из системы координат компо- нента в систему координат родительского компонента. Если компонент не имеет роди- теля, действует как метод mapToGlobal()
. Возвращает экземпляр класса
QPoint
;
 mapFromParent()
— преобразует координаты точки из системы координат роди- тельского компонента в систему координат текущего компонента. Если компонент не имеет родителя, работает подобно методу mapFromGlobal()
. Возвращает экземпляр клас- са
QPoint
;
 mapTo(, )
— преобразует координаты точки из системы координат текущего компонента в систему координат родительского компонента

. Воз- вращает экземпляр класса
QPoint
;
 mapFrom(, )
— преобразует координаты точки из системы координат родительского компонента

в систему координат текущего компонента. Воз- вращает экземпляр класса
QPoint

Глава 19. Обработка сигналов и событий
423 19.9.3. Наведение и увод указателя
Обработать наведение указателя мыши на компонент и увод его с компонента позволяют следующие методы:
 enterEvent(self, )
— вызывается при наведении указателя мыши на область компонента;
 leaveEvent(self, )
— вызывается, когда указатель мыши покидает область компонента.
Через параметр

доступен экземпляр класса
QEvent
, не несущий никакой дополни- тельной информации. Вполне достаточно знать, что указатель попал в область компонента или покинул ее.
19.9.4. Прокрутка колесика мыши
Все современные мыши комплектуются колесиком, обычно используемым для прокрутки содержимого компонента. Обработать поворот колесика позволяет метод wheelEvent(self,
)
. Через параметр

доступен экземпляр класса
QWheelEvent
, который позво- ляет получить дополнительную информацию о событии.
Класс
QWheelEvent поддерживает методы:
 angleDelta()
— возвращает угол поворота колесика в градусах, умноженный на 8, в ви- де экземпляра класса
QPoint
. Это значение может быть положительным или отрицатель- ным — в зависимости от направления поворота. Вот пример определения угла поворота колесика: angle = e.angleDelta() / 8 angleX = angle.x() angleY = angle.y()
 pixelDelta()
— возвращает величину поворота колесика в пикселах в виде экземпляра класса
QPoint
. Это значение может быть положительным или отрицательным — в зави- симости от направления поворота;
 x()
и y()
— возвращают координаты указателя в момент события по осям
X
и
Y
соответ- ственно в пределах области компонента;
 pos()
— возвращает экземпляр класса
QPoint с целочисленными координатами указате- ля в момент события в пределах области компонента;
 posF()
— возвращает экземпляр класса
QPointF
с вещественными координатами указа- теля в момент события в пределах области компонента;
 globalX()
и globalY()
— возвращают координаты указателя в момент события по осям
X
и
Y
соответственно в пределах экрана;
 globalPos()
— возвращает экземпляр класса
QPoint с целочисленными координатами указателя в момент события в пределах экрана;
 globalPosF()
— возвращает экземпляр класса
QPointF
с вещественными координатами указателя в момент события в пределах экрана;
 buttons()
— позволяет определить кнопки, которые нажаты одновременно с поворотом колесика. Возвращает комбинацию значений атрибутов, указанных в описании метода buttons()
(см. разд. 19.9.1). Вот пример определения нажатой кнопки мыши:

424
Часть II. Библиотека PyQt 5 if e.buttons() & QtCore.Qt.LeftButton: print("Нажата левая кнопка мыши")
 modifiers()
— позволяет определить, какие клавиши-модификаторы (, ,
и др.) были нажаты одновременно с поворотом колесика. Возможные значения мы уже рассматривали в разд. 19.8.3;
 timestamp()
— возвращает в виде числа отметку системного времени, в которое возник- ло событие.
Если событие было успешно обработано, необходимо вызвать метод accept()
объекта события. Чтобы родительский компонент мог получить событие, вместо метода accept()
необходимо вызвать метод ignore()
19.9.5. Изменение внешнего вида указателя мыши
Для изменения внешнего вида указателя мыши при вхождении его в область компонента предназначены следующие методы класса
QWidget
:
 setCursor(<Курсор>)
— задает внешний вид указателя мыши для компонента. В качест- ве параметра указывается экземпляр класса
QCursor или следующие атрибуты из класса
QtCore.Qt
:
ArrowCursor
(стандартная стрелка),
UpArrowCursor
(стрелка, направленная вверх),
CrossCursor
(крестообразный указатель),
WaitCursor
(песочные часы),
IBeamCursor
(I-образный указатель),
SizeVerCursor
(стрелки, направленные вверх и вниз),
SizeHorCursor
(стрелки, направленные влево и вправо),
SizeBDiagCursor
(стрелки, направленные в правый верхний угол и левый нижний угол),
SizeFDiagCursor
(стрелки, направленные в левый верхний угол и правый нижний угол),
SizeAllCursor
(стрелки, направленные вверх, вниз, влево и вправо),
SplitVCursor
(указатель изменения высоты),
SplitHCursor
(указатель изменения ширины),
PointingHandCursor
(указатель в виде руки),
ForbiddenCursor
(перечеркнутый круг),
OpenHandCursor
(разжатая рука),
ClosedHandCursor
(сжатая рука),
WhatsThisCursor
(стрелка с вопросительным знаком) и
BusyCursor
(стрелка с песочными часами): self.setCursor(QtCore.Qt.WaitCursor)
 unsetCursor()
— отменяет установку указателя для компонента. В результате внешний вид указателя мыши будет наследоваться от родительского компонента;
 cursor()
— возвращает экземпляр класса
QCursor
, представляющий текущий указатель.
Управлять видом указателя для всего приложения сразу можно с помощью следующих ста- тических методов из класса
QApplication
:
 setOverrideCursor(<Курсор>)
— задает внешний вид указателя мыши для всего прило- жения. В качестве параметра указывается экземпляр класса
QCursor или один из ранее упомянутых специальных атрибутов класса
QtCore.Qt
. Для отмены установки необхо- димо вызвать метод restoreOverrideCursor()
;
 restoreOverrideCursor()
— отменяет изменение внешнего вида указателя мыши для всего приложения:
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
# Выполняем длительную операцию
QtWidgets.QApplication.restoreOverrideCursor()
 changeOverrideCursor(<Курсор>)
— изменяет внешний вид указателя мыши для всего приложения. Если до вызова этого метода не вызывался метод setOverrideCursor()
,

Глава 19. Обработка сигналов и событий
425 значение будет проигнорировано. В качестве параметра указывается экземпляр класса
QCursor или один из специальных атрибутов класса
QtCore.Qt
;
 overrideCursor()
— возвращает экземпляр класса
QCursor
, представляющий текущий указатель, или значение
None
, если таковой не был изменен.
Изменять внешний вид указателя мыши для всего приложения принято на небольшой промежуток времени — обычно на время выполнения какой-либо операции, в процессе которой приложение не может нормально реагировать на действия пользователя. Чтобы информировать об этом пользователя, указатель принято выводить в виде песочных часов
(атрибут
WaitCursor
) или стрелки с песочными часами (атрибут
BusyCursor
).
Метод setOverrideCursor()
может быть вызван несколько раз. В этом случае курсоры помещаются в стек. Каждый вызов метода restoreOverrideCursor()
удаляет последний курсор, добавленный в стек. Для нормальной работы приложения необходимо вызывать методы setOverrideCursor()
и restoreOverrideCursor()
одинаковое количество раз.
Класс
QCursor позволяет создать объект курсора с изображением любой формы. Чтобы за- грузить изображение, следует передать конструктору класса
QPixmap путь к файлу изобра- жения. Для создания объекта курсора необходимо передать конструктору класса
QCursor в первом параметре экземпляр класса
QPixmap
, а во втором и третьем параметрах — коорди- наты «горячей» точки будущего курсора. Вот пример создания и установки пользователь- ского курсора: self.setCursor(QtGui.QCursor(QtGui.QPixmap("cursor.png"), 0, 0))
Класс
QCursor также поддерживает два статических метода:
 pos()
— возвращает экземпляр класса
QPoint с координатами указателя мыши относи- тельно экрана: p = QtGui.QCursor.pos() print(p.x(), p.y())
 setPos()
— позволяет задать позицию указателя мыши. Метод имеет два формата: setPos(, )
и setPos()
19.10. Технология drag & drop
Технология drag & drop позволяет обмениваться данными различных типов между компо- нентами как одного приложения, так и разных приложений, путем перетаскивания и сбра- сывания объектов с помощью мыши. Типичным примером использования технологии слу- жит перемещение файлов в Проводнике Windows. Чтобы переместить файл в другой ката- лог, достаточно нажать левую кнопку мыши над значком файла и, не отпуская кнопки, перетащить файл на значок каталога, а затем отпустить кнопку мыши. Если необходимо скопировать файл, следует дополнительно удерживать нажатой клавишу .
19.10.1. Запуск перетаскивания
Операция перетаскивания состоит из двух частей: первая часть запускает процесс, а вторая обрабатывает момент сброса объекта. Обе части могут обрабатываться как одним, так и двумя разными приложениями. Запуск перетаскивания осуществляется следующим об- разом:
1.
Внутри метода mousePressEvent()
запоминаются координаты указателя мыши в момент щелчка ее левой кнопкой.

426
Часть II. Библиотека PyQt 5 2.
Внутри метода mouseMoveEvent()
вычисляется пройденное расстояние или измеряется время операции. Это необходимо для того, чтобы предотвратить случайное перетаски- вание. Управлять задержкой позволяют следующие статические методы класса
QApplication
:
• setStartDragDistance(<Дистанция>)
— задает минимальное расстояние, после про- хождения которого будет запущена операция перетаскивания;
• startDragDistance()
— возвращает это расстояние;
• setStartDragTime(<Время>)
— задает время задержки в миллисекундах перед запус- ком операции перетаскивания;
• startDragTime()
— возвращает это время.
3.
Если пройдено минимальное расстояние или истек минимальный промежуток времени, создается экземпляр класса
QDrag
, и у него вызывается метод exec()
, который после за- вершения операции возвращает действие, выполненное с данными (например, их копи- рование или перемещение).
Создать экземпляр класса
QDrag можно так:
<Объект> = QtGui.QDrag(<Ссылка на компонент>)
Класс
QDrag поддерживает следующие методы:
 exec()
— запускает процесс перетаскивания и возвращает действие, которое было вы- полнено по завершении операции. Метод имеет два формата: exec([<Действия>=MoveAction]) exec(<Действия>, <Действие по умолчанию>)
В параметре
<Действия>
указывается комбинация допустимых действий, а в параметре
<Действие по умолчанию>
— действие, которое осуществляется, если в процессе выпол- нения операции не были нажаты клавиши-модификаторы. Возможные действия могут быть заданы следующими атрибутами класса
QtCore.Qt
:
CopyAction
(
1
, копирование),
MoveAction
(
2
, перемещение),
LinkAction
(
4
, создание ссылки),
IgnoreAction
(
0
, действие игнорировано),
TargetMoveAction
(
32770
): act = drag.exec(QtCore.Qt.MoveAction | QtCore.Qt.CopyAction,
QtCore.Qt.MoveAction)
Вместо метода exec()
можно использовать аналогичный метод exec_()
, сохраненный в PyQt 5 для совместимости с кодом, написанным под библиотеку PyQt 4;
 setMimeData()
— позволяет задать перемещаемые данные. В качестве значе- ния указывается экземпляр класса
QMimeData
. Вот пример передачи текста: data = QtCore.QMimeData() data.setText("Перетаскиваемый текст") drag = QtGui.QDrag(self) drag.setMimeData(data)
 mimeData()
— возвращает экземпляр класса
QMimeData с перемещаемыми данными;
 setPixmap()
— задает изображение, которое будет перемещаться вместе с ука- зателем мыши. В качестве параметра указывается экземпляр класса
QPixmap
: drag.setPixmap(QtGui.QPixmap("dd_representer.png"))
 pixmap()
— возвращает экземпляр класса
QPixmap с изображением, которое перемещает- ся вместе с указателем;

Глава 19. Обработка сигналов и событий
427
 setHotSpot()
— задает координаты «горячей» точки на перемещаемом изобра- жении. В качестве параметра указывается экземпляр класса
QPoint
: drag.setHotSpot(QtCore.QPoint(20, 20))
 hotSpot()
— возвращает экземпляр класса
QPoint с координатами «горячей» точки на перемещаемом изображении;
 setDragCursor(, <Действие>)
— позволяет изменить внешний вид указателя мыши для действия, указанного во втором параметре. Первым параметром передается экземпляр класса
QPixmap
, который, собственно, станет указателем мыши. Если в первом параметре указан пустой объект класса
QPixmap
, ранее установленный указатель для дей- ствия будет отменен. Вот пример изменения указателя для перемещения: drag.setDragCursor(QtGui.QPixmap("move_cursor.png"),
QtCore.Qt.MoveAction)
 dragCursor(<Действие>)
— возвращает экземпляр класса
QPixmap
, представляющий ука- затель мыши для заданного действия;
 source()
— возвращает ссылку на компонент-источник;
 target()
— возвращает ссылку на компонент-приемник или значение
None
, если компо- нент находится в другом приложении;
 supportedActions()
— возвращает значение, представляющее комбинацию допустимых в текущей операции действий. Возможные действия обозначаются упомянутыми ранее атрибутами класса
QtCore.Qt
;
 defaultAction()
— возвращает действие по умолчанию в виде одного из перечисленных ранее атрибутов класса
QtCore.Qt
Класс
QDrag поддерживает два сигнала:
 actionChanged(<Действие>)
— генерируется при изменении действия. Новое действие представляется одним из упомянутых ранее атрибутов класса
QtCore.Qt
;
 targetChanged(<Компонент>)
— генерируется при изменении принимающего компонен- та, который представляется экземпляром соответствующего класса.
Вот пример назначения обработчиков сигналов: drag.actionChanged.connect(self.on_action_changed) drag.targetChanged.connect(self.on_target_changed)
19.10.2. Класс QMimeData
Перемещаемые данные и сведения о MIME-типе должны быть представлены экземпляром класса
QMimeData
. Его следует передать в метод setMimeData()
класса
QDrag
. Выражение, создающее экземпляр класса
QMimeData
, выглядит так: data = QtCore.QMimeData()
Класс
QMimeData поддерживает следующие полезные для нас методы (полный их список приведен на странице https://doc.qt.io/qt-5/qmimedata.html):
 setText(<Текст>)
— устанавливает текстовые данные (MIME-тип text/plain
): data.setText("Перетаскиваемый текст")
 text()
— возвращает текстовые данные;

428
Часть II. Библиотека PyQt 5
 hasText()
— возвращает значение
True
, если объект содержит текстовые данные, и
False
— в противном случае;
 setHtml(
1   ...   35   36   37   38   39   40   41   42   ...   83


написать администратору сайта