将Radialbar QML端口与PyQt5一起使用

2024-06-16 12:09:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在我正在创建的GUI中使用一个“Radialbar”小部件来达到美观的目的。当前,我正在尝试使用在以下位置找到的端口:

http://pyjuice.com/porting-radialbar-cqt-pyqt/

我的问题是,如何在我已经构建的GUI中使用它呢?我目前使用Qt Designer创建用于GUI的ui文件,然后使用以下命令导入PtQt5:

    uic.loadUi("name.ui")

有没有办法把这个小部件包含到我现有的GUI中?我对这一点很陌生,不知道应该如何使用上面的链接中的端口。在


Tags: 端口目的comhttpui部件guiqt
1条回答
网友
1楼 · 发布于 2024-06-16 12:09:04

有几个选项:

1。转换为QWidget

对您来说,最简单的选择是将QQuickPaintedItem转换为QWidget,这样就避免了学习使用QML,这对初学者来说不是一个简单的任务。在

为此,必须进行一些更改:

  • 在setters中使用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()      
        ...
    
  • 最后,QWidget没有setWidth()setHeight()方法,必须使用resize()方法。在

使用以上所有方法,您必须创建一个名为拉比阿尔巴. 在

半径巴.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_())

enter image description here

如果你想在Qt设计器中使用它,有两个选择:创建一个对初学者来说很繁重和不必要的插件,或者推广它,第二种方法就是我要建议的方法。在

为此,您必须在设计中添加一个小部件:

enter image description here

enter image description here

然后右键单击窗口小部件所在的部分并单击“升级到…”,然后在对话框中放置RadialBar,如下所示:

enter image description here

然后按“添加”按钮,然后按“升级”按钮。在

上面生成的.ui是:

名称.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文件:

主.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_())

enter image description here

您必须具有以下结构:

├── main.py
├── name.ui
└── radialbar.py

相关问题 更多 >