简体   繁体   中英

PySide2 repaint on widget when qcombobox index changes overriding QUiloader

Using VS Code on Win10 and Python 3.6.6.

This link provides the same approach for creating graphics on a promoted widget which I'm using:

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

I want to be able to create some other graphics based on what shape is selected in the qcombobox. The two issues I got with this is:

  1. returning the index or string value from combobox with a function/method to my Drawer class. This approach, https://stackoverflow.com/a/56560455/6284847 , shows how to print the index/string value from a class, but I'm not able to return qcombobox index/string value in a function/method and use the function/method in another class. I've read that it's not possible to return these values in different SO topics but there have to be a way to accomplish this.

  2. I don't really have an idea of how to repaint the widget other than when the application run initially.

Any other way to restructure these things too accomplish this is much appreciated!

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

EDIT 1:

I've tried to get my index or value from my qcombobox but I'm not able to achieve it. I've updated myDrawWidget.py and commented where I think I have to implement code to reach my goal which is to draw different shape colours when qcombobox is activated.

So it was an easy fix for this issue. First we have to connect to the returnComboBoxIndex in Drawer.py and then assign the class variable Drawer.index , which was already made, to the returned index.

paintEventTest.py

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

myDrawWidget.py

Changing this

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

to this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM