Get QComboBox item text triggered by event in separate class method/function

妖精的绣舞 提交于 2020-01-24 19:39:12

问题


I'm having trouble getting any information from a QComboBox other than the index in a function. Most similar examples provides the function in the same class as the triggered event. I'm trying to get this from an external class (and file).

Folder structure is as provided in the answer here:

  • PySide2 paint on widget created by designer

In paintEventTest.py I've created a list which is used to populate the combobox with items. ComboEvent is instantiated from EventMethods.py and I'm trying to print the itemText in my function.

EventMethods.py

from PySide2.QtWidgets import QWidget, QPushButton, QComboBox

class widgetEventHandler(QWidget):

    def closeEvent(self, event):
        print("TEST")


class comboBoxEvent(QComboBox):
    def getSectionShape(self, index):
        text = str(self.itemText(index))
        print(text)
        print("Index changed to: " + str(index))

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 EventMethods import *


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 = QUiLoader()
        self.ui_window = loader.load(ui_file)
        ui_file.close()
        self.ui_window.show()

        #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(self)
        comboBox.currentIndexChanged.connect(comboEvent.getSectionShape)


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

testUI.ui file looks like this and is in a folder "UI designer":

<?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>

When debugging the text string in getSectionShape is empty (expecting section type) but my index is correct. Console prints one blank and one correct line. Something isn't working with the self.itemText(index) in getSectionShape form EventMethods.py. Any help is appreciated!


回答1:


What does self.itemText(index) mean in comboBoxEvent? since you are getting the text of the current comboBoxEvent item. Does comboBoxEvent have items? No, it is empty, only the QComboBox that is in the window has the items, comboBoxEvent is not the QComboBox in the window. That explains why you do not get anything.

According to what you want to do there are the following methods:

1. If you just want to get the currentText then use the currentTextChanged signal, comboBoxEvent does not have to inherit from a QComboBox.

class comboBoxEvent:
    def getSectionShape(self, text):
        print(text)
# ...
comboBox = self.ui_window.comboBox
comboBox.setCurrentIndex(0)
for item in sectionList:
    comboBox.addItem(item)
self.comboEvent = comboBoxEvent()
comboBox.currentTextChanged.connect(self.comboEvent.getSectionShape)
# ...

2. If you want to get all the possible information of the QComboBox when a new item is selected then it is better to get the QComboBox in getSectionShape, for this there are the following possibilities.

2.1 Make comboBoxEvent a QObject so that the QComboBox can be obtained using the sender() method in the slot:

from PySide2 import QtCore, QtWidgets


class comboBoxEvent(QtCore.QObject):
    @QtCore.Slot()
    def getSectionShape(self):
        obj = self.sender()
        if isinstance(obj, QtWidgets.QComboBox):
            index = obj.currentIndex()
            text = obj.itemText(index)
            print(text)
            print("Index changed to: {}".format(index))
# ...
comboBox = self.ui_window.comboBox
comboBox.setCurrentIndex(0)
for item in sectionList:
    comboBox.addItem(item)
comboEvent = comboBoxEvent(self)
comboBox.currentIndexChanged.connect(comboEvent.getSectionShape)
# ...

2.2 Pass the QComboBox through functools.partial:

class comboBoxEvent:
    def getSectionShape(self, combo, index):
        index = combo.currentIndex()
        text = combo.itemText(index)
        print(text)
        print("Index changed to: {}".format(index))
from functools import partial

# ...
comboBox = self.ui_window.comboBox
comboBox.setCurrentIndex(0)
for item in sectionList:
    comboBox.addItem(item)
self.comboEvent = comboBoxEvent()
comboBox.currentIndexChanged.connect(partial(self.comboEvent.getSectionShape, comboBox))
# ...
  1. Pass the QComboBox through lambda
class comboBoxEvent:
    def getSectionShape(self, combo):
        index = combo.currentIndex()
        text = combo.itemText(index)
        print(text)
        print("Index changed to: {}".format(index))
# ...
comboBox = self.ui_window.comboBox
comboBox.setCurrentIndex(0)
for item in sectionList:
    comboBox.addItem(item)
self.comboEvent = comboBoxEvent()
comboBox.currentIndexChanged.connect(lambda ix, c= comboBox: self.comboEvent.getSectionShape(c))
# ...


来源:https://stackoverflow.com/questions/56557896/get-qcombobox-item-text-triggered-by-event-in-separate-class-method-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!