python - 当 qcombobox 索引更改覆盖 QUiloader 时,PySide2 在小部件上重新绘制

标签 python python-3.x qt-designer pyside2 qcombobox

在 Win10 和 Python 3.6.6 上使用 VS Code。

此链接提供了在我正在使用的升级小部件上创建图形的相同方法:

https://stackoverflow.com/a/56492312/6284847

我希望能够根据 qcombobox 中选择的形状创建一些其他图形。我遇到的两个问题是:

  1. 使用函数/方法将组合框中的索引或字符串值返回到我的 Drawer 类。这种方法,https://stackoverflow.com/a/56560455/6284847 ,展示了如何从类中打印索引/字符串值,但我无法在函数/方法中返回 qcombobox 索引/字符串值并在另一个类中使用该函数/方法。我读到不可能在不同的 SO 主题中返回这些值,但必须有一种方法来实现这一点。

  2. 除了应用程序最初运行时之外,我真的不知道如何重新绘制小部件。

任何其他方式来重组这些事情也能实现这一点,我们非常感激!

testUI.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>996</width>
    <height>892</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QGraphicsView" name="graphicsView">
      <property name="minimumSize">
       <size>
        <width>0</width>
        <height>200</height>
       </size>
      </property>
     </widget>
    </item>
    <item>
     <widget class="Drawer" name="widget" native="true">
      <property name="minimumSize">
       <size>
        <width>0</width>
        <height>250</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
        <width>16777215</width>
        <height>300</height>
       </size>
      </property>
      <property name="styleSheet">
       <string notr="true"/>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QComboBox" name="comboBox"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>996</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <customwidgets>
  <customwidget>
   <class>Drawer</class>
   <extends>QWidget</extends>
   <header>myDrawWidget</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

paintEventTest.py

import sys

from PySide2 import QtWidgets 
from PySide2 import QtGui
from PySide2 import QtCore
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import (
    QApplication, QPushButton, QLineEdit, QTextEdit, QSpinBox, QMainWindow, QDesktopWidget, QTableWidget, 
    QTableWidgetItem, QToolButton, QToolTip)
from PySide2.QtCore import QFile, QObject, Qt

from  myDrawWidget import Drawer

class UiLoader(QUiLoader):
    def createWidget(self, className, parent=None, name=""):
        if className == "Drawer":
            widget = Drawer(parent)
            widget.setObjectName(name)
            return widget
        return super(UiLoader, self).createWidget(className, parent, name)

class MainForm(QMainWindow):
    def __init__(self, ui_file, parent=None):
        super(MainForm, self).__init__(parent)
        ui_file = QtCore.QFile(ui_file)
        ui_file.open(QtCore.QFile.ReadOnly)

        ### Load UI file from Designer ###
        loader = UiLoader()
        self.ui_window = loader.load(ui_file)
        ui_file.close()
        self.initUI()

        self.ui_window.show()



    def initUI(self):

        #region widget code
        widget = self.ui_window.widget
        widget.setStyleSheet("""
            QWidget {
                border: 1px solid lightgrey;
                border-radius: 2px;
                background-color: rgb(255, 255, 255);
                }
            """)

        #endregion

        sectionList = []
        sectionList.append("Rectangle")
        sectionList.append("Diamond")
        sectionList.append("Circle")
        sectionList.append("Box")
        sectionList.append("T-Section")
        sectionList.append("I-Section")

        ComboBox = self.ui_window.comboBox
        #comboBox = QtWidgets.QComboBox      #Just to get intellisense working. Gets commented out
        ComboBox.setCurrentIndex(0)

        for item in sectionList:
            ComboBox.addItem(item)

        #ComboEvent = comboBoxEvent(ComboBox)
        ComboBox.currentIndexChanged.connect(self.cbEvent)
        # #print(ComboBox.itemText(ComboBox.currentIndex()))

    def cbEvent(self, index):
        text = self.ui_window.comboBox.itemText(index)
        print(str(text))    


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle('Fusion')
    form = MainForm('./UI_designer/testUI.ui')
    sys.exit(app.exec_())

myDrawWidget.py

class Drawer(QtWidgets.QWidget):

    index = None

    def paintEvent(self, e):
        '''
        the method paintEvent() is called automatically
        the QPainter class does all the low-level drawing
        coded between its methods begin() and end()
        '''
        index = Drawer.index

        ##############################################
        # IMPLEMENT CODE TO GET INDEX FROM QCOMBOBOX
        # HOW TO?
        ##############################################



        ### Applying QSS style on the widget ###
        opt = QtWidgets.QStyleOption()
        opt.init(self)

        qp = QtGui.QPainter()
        qp.begin(self)
        self.style().drawPrimitive(QtWidgets.QStyle.PE_Widget, opt, qp, self)

        if index == None:
            self.init_drawGeometry(qp)
        elif cb_index == 0:

            self.drawGeometry(qp)
        else:
            self.drawGeometry_two(qp)

        qp.end()


    def init_drawGeometry(self, qp):
        qp = QtGui.QPainter(self)
        qp.setPen(QtGui.QPen(QtCore.Qt.red, 8, QtCore.Qt.DashLine))
        qp.drawEllipse(40, 40, 400, 400)

    def drawGeometry(self, qp):
        qp = QtGui.QPainter(self)
        qp.setPen(QtGui.QPen(QtCore.Qt.green, 8, QtCore.Qt.DashLine))
        qp.drawEllipse(40, 40, 400, 400)

    def drawGeometry_two(self, qp):
        qp = QtGui.QPainter(self)
        qp.setPen(QtGui.QPen(QtCore.Qt.blue, 8, QtCore.Qt.DashLine))
        qp.drawEllipse(40, 40, 400, 400)

    @QtCore.Slot()
    def returnComboBoxIndex(self, index):
        print(index)
        return index

编辑1:

我尝试从 qcombobox 获取索引或值,但无法实现。我已经更新了 myDrawWidget.py 并评论了我认为我必须实现代码才能达到我的目标的地方,即在激活 qcombobox 时绘制不同的形状颜色。

最佳答案

所以这个问题很容易解决。首先,我们必须连接到 Drawer.py 中的 returnComboBoxIndex,然后将已经创建的类变量 Drawer.index 分配给返回的索引。

paintEventTest.py

    cb_event = Drawer(self)
    ComboBox.activated[int].connect(cb_event.returnComboBoxIndex)

myDrawWidget.py

改变这个

    @QtCore.Slot()
    def returnComboBoxIndex(self, index):
        print(index)
        return index

对此:

    @QtCore.Slot()
    def returnComboBoxIndex(self, index):
    Drawer.index = index    
    print(index)

关于python - 当 qcombobox 索引更改覆盖 QUiloader 时,PySide2 在小部件上重新绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58837335/

相关文章:

python - 使用 Python 和 Gstreamer 进行音频转换

python - 从 excel 中读取专栏并进行特定的数学运算

python - Opencv 单应性不产生所需的转换

python - 阈值必须是数字且非NAN,打印numpy数组时,为什么numpy.nan在python3中未定义

python - 在 Qt Designer 中创建可滑动窗口/框架

python - 如何使用复杂的自定义 id 作为选择器在 pytest 中运行单个测试?

循环时Python缩进错误

python - 如何对所有变量使用describe() by group?

python - 单击 QPushButton 时,它会触发两次

python - 显示网络摄像头Python