我想在我正在创建的GUI中出于美学目的使用“ Radialbar”小部件。当前,我正在尝试使用在以下位置找到的端口:
http://pyjuice.com/porting-radialbar-cqt-pyqt/
我的问题是,我实际上如何在已经构建的GUI中使用它?我目前使用Qt Designer创建用于GUI的ui文件,然后使用以下命令将其导入PtQt5:
uic.loadUi("name.ui")
有没有办法将此小部件包含到我现有的GUI中?我对此很陌生,不了解如何使用上面的链接使用端口。
答案 0 :(得分:1)
有几种选择:
对您来说,最简单的选择是将QQuickPaintedItem
转换为QWidget
,这样就避免了学习使用QML的知识,这对初学者来说并非易事。
为此,必须进行一些更改:
在设置器中使用update()
方法:
@SOME_PROPERTY.setter
def SOME_PROPERTY(self, type):
...
self.SOME_PROPERTYChanged.emit()
self.update() # <----
将paint()
方法更改为paintEvent()
并创建QPainter
,因为paintEvent()
不提供任何内容。
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.save()
...
setWidth()
或setHeight()
方法,您必须使用resize()
方法。使用以上所有内容,您都必须创建一个名为radiusbar.py的.py文件。
radialbar.py
from PyQt5 import QtCore, QtGui, QtWidgets
class RadialBar(QtWidgets.QWidget):
class DialType():
FullDial = 0
MinToMax = 1
NoDial = 2
sizeChanged = QtCore.pyqtSignal()
startAngleChanged = QtCore.pyqtSignal()
spanAngleChanged = QtCore.pyqtSignal()
minValueChanged = QtCore.pyqtSignal()
maxValueChanged = QtCore.pyqtSignal()
valueChanged = QtCore.pyqtSignal()
dialWidthChanged = QtCore.pyqtSignal()
backgroundColorChanged = QtCore.pyqtSignal()
foregroundColorChanged = QtCore.pyqtSignal()
progressColorChanged = QtCore.pyqtSignal()
textColorChanged = QtCore.pyqtSignal()
suffixTextChanged = QtCore.pyqtSignal()
showTextChanged = QtCore.pyqtSignal()
penStyleChanged = QtCore.pyqtSignal()
dialTypeChanged = QtCore.pyqtSignal()
textFontChanged = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(RadialBar, self).__init__(parent)
self.resize(200, 200)
# self.setSmooth(True)
# self.setAntialiasing(True)
self._Size = 200
self._StartAngle = 40
self._SpanAngle = 280
self._MinValue = 0
self._MaxValue = 100
self._Value = 50
self._DialWidth = 15
self._BackgroundColor = QtCore.Qt.transparent
self._DialColor = QtGui.QColor(80,80,80)
self._ProgressColor = QtGui.QColor(135,26,5)
self._TextColor = QtGui.QColor(0, 0, 0)
self._SuffixText = ""
self._ShowText = True
self._PenStyle = QtCore.Qt.FlatCap
self._DialType = RadialBar.DialType.MinToMax
self._TextFont = QtGui.QFont()
def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.save()
r = min(self.width(), self.height())
rect = QtCore.QRectF(0, 0, r, r) #self.boundingRect()
painter.setRenderHint(QtGui.QPainter.Antialiasing)
pen = painter.pen()
pen.setCapStyle(self._PenStyle)
startAngle = -90 - self._StartAngle
if RadialBar.DialType.FullDial != self._DialType:
spanAngle = 0 - self._SpanAngle
else:
spanAngle = -360
#Draw outer dial
painter.save()
pen.setWidth(self._DialWidth)
pen.setColor(self._DialColor)
painter.setPen(pen)
offset = self._DialWidth / 2
if self._DialType == RadialBar.DialType.MinToMax:
painter.drawArc(rect.adjusted(offset, offset, -offset, -offset), startAngle * 16, spanAngle * 16)
elif self._DialType == RadialBar.DialType.FullDial:
painter.drawArc(rect.adjusted(offset, offset, -offset, -offset), -90 * 16, -360 * 16)
else:
pass
#do not draw dial
painter.restore()
#Draw background
painter.save()
painter.setBrush(self._BackgroundColor)
painter.setPen(self._BackgroundColor)
inner = offset * 2
painter.drawEllipse(rect.adjusted(inner, inner, -inner, -inner))
painter.restore()
#Draw progress text with suffix
painter.save()
painter.setFont(self._TextFont)
pen.setColor(self._TextColor)
painter.setPen(pen)
if self._ShowText:
painter.drawText(rect.adjusted(offset, offset, -offset, -offset), QtCore.Qt.AlignCenter,str(self._Value) + self._SuffixText)
else:
painter.drawText(rect.adjusted(offset, offset, -offset, -offset), QtCore.Qt.AlignCenter, self._SuffixText)
painter.restore()
#Draw progress bar
painter.save()
pen.setWidth(self._DialWidth)
pen.setColor(self._ProgressColor)
valueAngle = float(float(self._Value - self._MinValue)/float(self._MaxValue - self._MinValue)) * float(spanAngle) #Map value to angle range
painter.setPen(pen)
painter.drawArc(rect.adjusted(offset, offset, -offset, -offset), startAngle * 16, valueAngle * 16)
painter.restore()
@QtCore.pyqtProperty(str, notify=sizeChanged)
def size(self):
return self._Size
@size.setter
def size(self, size):
if self._Size == size:
return
self._Size = size
self.sizeChanged.emit()
self.update()
@QtCore.pyqtProperty(int, notify=startAngleChanged)
def startAngle(self):
return self._StartAngle
@startAngle.setter
def startAngle(self, angle):
if self._StartAngle == angle:
return
self._StartAngle = angle
self.startAngleChanged.emit()
self.update()
@QtCore.pyqtProperty(int, notify=spanAngleChanged)
def spanAngle(self):
return self._SpanAngle
@spanAngle.setter
def spanAngle(self, angle):
if self._SpanAngle == angle:
return
self._SpanAngle = angle
self.spanAngleChanged.emit()
self.update()
@QtCore.pyqtProperty(int, notify=minValueChanged)
def minValue(self):
return self._MinValue
@minValue.setter
def minValue(self, value):
if self._MinValue == value:
return
self._MinValue = value
self.minValueChanged.emit()
self.update()
@QtCore.pyqtProperty(int, notify=maxValueChanged)
def maxValue(self):
return self._MaxValue
@maxValue.setter
def maxValue(self, value):
if self._MaxValue == value:
return
self._MaxValue = value
self.maxValueChanged.emit()
self.update()
@QtCore.pyqtProperty(float, notify=valueChanged)
def value(self):
return self._Value
@value.setter
def value(self, value):
if self._Value == value:
return
self._Value = value
self.valueChanged.emit()
self.update()
@QtCore.pyqtProperty(int, notify=dialWidthChanged)
def dialWidth(self):
return self._DialWidth
@dialWidth.setter
def dialWidth(self, width):
if self._DialWidth == width:
return
self._DialWidth = width
self.dialWidthChanged.emit()
self.update()
@QtCore.pyqtProperty(QtGui.QColor, notify=backgroundColorChanged)
def backgroundColor(self):
return self._BackgroundColor
@backgroundColor.setter
def backgroundColor(self, color):
if self._BackgroundColor == color:
return
self._BackgroundColor = color
self.backgroundColorChanged.emit()
self.update()
@QtCore.pyqtProperty(QtGui.QColor, notify=foregroundColorChanged)
def foregroundColor(self):
return self._ForegrounColor
@foregroundColor.setter
def foregroundColor(self, color):
if self._DialColor == color:
return
self._DialColor = color
self.foregroundColorChanged.emit()
self.update()
@QtCore.pyqtProperty(QtGui.QColor, notify=progressColorChanged)
def progressColor(self):
return self._ProgressColor
@progressColor.setter
def progressColor(self, color):
if self._ProgressColor == color:
return
self._ProgressColor = color
self.progressColorChanged.emit()
self.update()
@QtCore.pyqtProperty(QtGui.QColor, notify=textColorChanged)
def textColor(self):
return self._TextColor
@textColor.setter
def textColor(self, color):
if self._TextColor == color:
return
self._TextColor = color
self.textColorChanged.emit()
self.update()
@QtCore.pyqtProperty(str, notify=suffixTextChanged)
def suffixText(self):
return self._SuffixText
@suffixText.setter
def suffixText(self, text):
if self._SuffixText == text:
return
self._SuffixText = text
self.suffixTextChanged.emit()
self.update()
@QtCore.pyqtProperty(str, notify=showTextChanged)
def showText(self):
return self._ShowText
@showText.setter
def showText(self, show):
if self._ShowText == show:
return
self._ShowText = show
self.update()
@QtCore.pyqtProperty(QtCore.Qt.PenCapStyle, notify=penStyleChanged)
def penStyle(self):
return self._PenStyle
@penStyle.setter
def penStyle(self, style):
if self._PenStyle == style:
return
self._PenStyle = style
self.penStyleChanged.emit()
self.update()
@QtCore.pyqtProperty(int, notify=dialTypeChanged)
def dialType(self):
return self._DialType
@dialType.setter
def dialType(self, type):
if self._DialType == type:
return
self._DialType = type
self.dialTypeChanged.emit()
self.update()
@QtCore.pyqtProperty(QtGui.QFont, notify=textFontChanged)
def textFont(self):
return self._TextFont
@textFont.setter
def textFont(self, font):
if self._TextFont == font:
return
self._TextFont = font
self.textFontChanged.emit()
self.update()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = RadialBar()
w.backgroundColor = QtGui.QColor("#1dc58f")
w.foregroundColor = QtGui.QColor("#191a2f")
w.dialWidth = 10
w.spanAngle = 70
w.textColor = QtGui.QColor("#FFFFFF")
w.penStyle = QtCore.Qt.RoundCap
w.dialType = RadialBar.DialType.FullDial
w.suffixText = "%"
timeline = QtCore.QTimeLine(10000, w)
timeline.setFrameRange(0, 100)
timeline.frameChanged.connect(lambda val: setattr(w, "value", val))
timeline.start()
w.show()
sys.exit(app.exec_())
如果您想在Qt Designer中使用它,则有两种选择:创建一个对初学者来说可能既繁琐又不必要的插件,或者对其进行推广,这是我将要提出的第二种方法。
为此,您必须在设计中添加一个小部件:
然后右键单击窗口小部件所在的部分,然后单击“升级为..”,然后在对话框中显示RadialBar,如下所示:
然后按“添加”按钮,然后按“升级”按钮。
在上面生成的.ui是:
name.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="RadialBar" name="widget" native="true"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RadialBar</class>
<extends>QWidget</extends>
<header>radialbar.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
最后,您使用您的.ui文件:
main.py
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class Widget(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
uic.loadUi("name.ui", self)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
您必须具有的结构如下:
├── main.py
├── name.ui
└── radialbar.py