Казалось бы, что может быть проще обычной кнопки с её стандартным поведением и привычным всему миру видом? Однако, сам процесс создания своей кнопки не менее интересен, чем создание целого приложения с помощью PyQt4.
Здесь приводится пример создания в QGraphicsScene своей рисованной кнопки с помощью QGraphicsWidget.
Рекомендуется к прочтению людям, имеющим опыт работы с PyQt4.
Для начала, разберёмся, что из себя представляет кнопка.
Обычная кнопка — это, чаще всего, прямоугольник с текстом и/или картинкой, щелчок мышью на который сопровождается визуальным откликом. Основное назначение кнопок — реагировать на простое событие нажатия и отжатия указателем мыши (или пальцем), находящегося в поле координат этой кнопки.
- # -*- coding: utf-8 -*-
- from PyQt4 import QtCore, QtGui
- import sys
- class AButton(QtGui.QGraphicsWidget):
- # нажата ли кнопка мыши
- mouse_isPressed = False
- def __init__(self, parent = None):
- QtGui.QGraphicsWidget.__init__(self)
- def boundingRect(self):
- # размеры кнопки
- # для наглядности возвращается фиксированное значение
- # хотя можно считать размеры текста и иконки и
- # использовать их динамически.
- # QRectF, в отличие от QRect, позволяет оперировать
- # числами с плавающей точкой.
- return QtCore.QRectF(0, 0, 40, 40)
- def paint(self, painter, option, widget = 0):
- # метод прорисовки кнопки со стилями
- opt = QtGui.QStyleOptionButton()
- # стиль нажатой и отжатой кнопки в зависимости от того,
- # нажата ли кнопка мыши
- opt.state = ((QtGui.QStyle.State_Sunken if self.mouse_isPressed else QtGui.QStyle.State_Raised) | QtGui.QStyle.State_Enabled)
- # текст на кнопке
- opt.text = self.text()
- # иконка кнопки
- opt.icon = self.icon()
- # геометрия
- opt.rect = option.rect
- # палитра для стиля
- opt.palette = option.palette
- # сама прорисовка кнопки с определённым выше стилем и опциями
- QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_PushButton, opt, painter)
- def text(self):
- # метод, возвращающий текст, отображаемый на кнопке
- # для наглядности возвращаем фиксированное значение
- return QtCore.QString("hi")
- def icon(self):
- # метод, возвращающий иконку кнопки
- # пока возвращаем пустую иконку
- # вроде можно использовать QPixmap вместо QIcon
- return QtGui.QIcon()
- def mousePressEvent(self, event):
- # событие нажания кнопки мыши и обновление
- # внешнего вида состояния кнопки
- self.mouse_isPressed = True
- self.update()
- def mouseReleaseEvent(self, event):
- # отжатие кнопки
- self.mouse_isPressed = False
- # метод update - обязательный, он отвечает за перерисовку
- # любого графического виджета
- self.update()
- if __name__ == "__main__":
- app = QtGui.QApplication(sys.argv)
- # создаём графическую область, на которой будет рисоваться
- # наша кнопка
- scene = QtGui.QGraphicsScene()
- # создаём кнопку
- button = AButton()
- # добавляем кнопку в графическую область
- scene.addItem(button)
- # и создаём графическое поле, на которое накладывается
- # графическая область с кнопкой
- view = QtGui.QGraphicsView(scene)
- # сглаживание
- view.setRenderHint(QtGui.QPainter.Antialiasing)
- # задаём размер графического поля
- view.resize(200, 100)
- # фон
- view.setBackgroundBrush(QtGui.QApplication.palette().background())
- view.show()
- sys.exit(app.exec_())
В моём случае, этот код исправно работает в PyQt 4.9.1 for Python 2.7.
Конечно, эта кнопка далека от совершенства, однако нашей целью было понимание того, как рисовать свои виджеты в графической области и делать их интерактивными. В общем-то, это основы, отталкиваясь от которых и изменяя их, можно добиться практически любой реализации своих замыслов и попрактиковаться в творчестве, будучи программистом.
Изначально, вышеописанный код был найден в интернете, написанный на C++, благополучно сохранён на компьютер, а источник утерян. Позже и сам код был переписан на язык Python с некоторыми особенностями, а оригинал удалён с компьютера.
Благодарю за внимание.
Автор: Chrizt