Хотя создание плагинов для Qt Designer возможно, это не простая задача: официальная документация устарела, а иногда и неполна, а некоторые функции не полностью перенесены для прозрачного использования PyQt.
Самый простой способ - использовать продвинутые виджеты .
Допустим, у вас есть виджет, который причудливо отображает текущее время:
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class TimeFrame(QtWidgets.QFrame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.updateTimer = QtCore.QTimer(interval=60000, timeout=self.update)
self._time = None
@QtCore.pyqtProperty(QtCore.QTime)
def time(self):
return self._time
@time.setter
def time(self, time):
self._time = time
self.update()
def paintEvent(self, event):
super().paintEvent(event)
size = min(self.width(), self.height()) - 10
rect = QtCore.QRect(0, 0, size, size)
rect.moveCenter(self.rect().center())
qp = QtGui.QPainter(self)
qp.setRenderHints(qp.Antialiasing)
qp.drawEllipse(rect)
qp.setPen(QtCore.Qt.NoPen)
qp.setBrush(QtCore.Qt.blue)
time = self._time or QtCore.QTime.currentTime()
minuteAngle = time.minute() * 6
qp.drawPie(rect, 1440, -minuteAngle * 16)
qp.setBrush(QtCore.Qt.red)
hourAngle = (time.hour() % 12 + time.minute() / 60) * 30
qp.drawPie(rect.adjusted(30, 30, -30, -30), 1440, -hourAngle * 16)
Это простой виджет часов, который показывает пару «пирогов», чем больше минут, тем меньше часов (на этом скриншоте время 2:03):
Теперь, чтобы иметь возможность добавить этот виджет из Designer, вам нужно повысить виджет. Продвижение виджетов - это способ для Qt расширить возможности и функциональные возможности виджета, добавленного в пользовательский интерфейс.
Это очень полезно, потому что вы можете расширить любой стандартный класс виджетов по-своему: например Если вы добавляете QTableView в пользовательский интерфейс и продвигаете его, он позволяет вам установить стандартные свойства QPushButton из интерфейса Designer, а затем реализовать другие функции из вашего кода.
Процедура довольно проста, если вы знать, как это работает.
1. Создайте пользовательский интерфейс и добавьте виджет на основе класса, который вы хотите расширить
В этом случае я использую QFrame, чтобы показать, как можно расширить свойства этого класса. Просто создайте свой интерфейс и добавьте QFrame в макет.
Как вы можете видеть, класс, сообщаемый из инспектора объектов, по-прежнему является QFrame .
2. Продвигайте виджет
Щелкните правой кнопкой мыши на виджете, который вы хотите использовать для своего класса, и выберите Promote to...
, затем установите «Имя продвигаемого класса» для имени класса виджета, созданного ранее, и «Файл заголовка» к имени модуля , содержащему этот класс. Я сохранил файл python как promoted.py
, поэтому значение поля будет promoted
. Учтите, что пути к файлам заголовков относятся к пути, из которого будет загружен файл пользовательского интерфейса.
Затем нажмите «Добавить», чтобы создать новый продвинутый виджет "класс" и, наконец, "продвижение", чтобы официально продвигать его. После этого вы можете перевести любой виджет в ранее установленный продвигаемый класс, если базовый класс совместим: если у вас есть другой QFrame в вашем интерфейсе, вы можете щелкнуть по нему правой кнопкой мыши и выбрать продвинутый класс из «Повышать в» подменю.
Теперь класс, отображаемый в Инспекторе объектов, равен TimeFrame
.
3. Задайте свойства объекта, сохраните, создайте код и запустите
Поскольку мы используем QFrame, мы можем установить его фрейм (это потому, что мы ранее также вызывали реализацию базового класса в методе paintEvent(event)
).
Теперь вам просто нужно реализовать базовый класс для основного виджета. Помните, что каждый раз, когда загружаемый виджет загружается, его «заголовочный файл» будет загружен, что означает, что его код будет всегда выполняться. Вот почему важно, чтобы кодовый блок if __name__ == '__main__':
помещался в файл, если он содержит как основную «программу», так и продвигаемый класс виджетов.
promoted.py
code:
class Test(QtWidgets.QWidget):
def __init__(self):
super().__init__()
uic.loadUi('test.ui', self)
self.timeEdit.timeChanged.connect(self.updateTimeFrame)
self.timeEdit.setTime(QtCore.QTime.currentTime())
def updateTimeFrame(self):
self.timeFrame.time = self.timeEdit.time()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Test()
w.show()
sys.exit(app.exec())
Теперь, очевидно, в Designer в любом случае ничего не будет отображаться, , но , как только мы запустим наш код, продвинутый виджет будет отображаться, как и ожидалось!
И теперь вы также можете узнать, сколько времени мне понадобилось, чтобы создать этот ответ, круто; -)