在单独的 class method/function 中获取事件触发的 QComboBox 项目文本

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

我无法从 QComboBox 获取除函数中的索引以外的任何信息。大多数类似的示例在与触发事件相同的 class 中提供函数。我正在尝试从外部 class(和文件)获取它。

文件夹结构在此处的答案中提供:

在 paintEventTest.py 中,我创建了一个列表,用于用项目填充组合框。 ComboEvent 是从 EventMethods.py 实例化的,我正在尝试在我的函数中打印 itemText。

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 文件如下所示,位于文件夹 "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>

调试时,getSectionShape 中的文本字符串为空(应为节类型),但我的索引是正确的。控制台打印一行空白和一行正确。 getSectionShape 形式 EventMethods.py 中的 self.itemText(index) 有问题。感谢您的帮助!

comboBoxEvent 中的 self.itemText(index) 是什么意思? 因为您正在获取当前 comboBoxEvent 项目的文本。 comboBoxEvent有item吗?没有,是空的,只有window中的QComboBox有item,comboBoxEvent不是window中的QComboBox。这就解释了为什么你没有得到任何东西。

根据你要做的事情有以下几种方法:

1.如果你只想得到currentText然后使用currentTextChanged信号,comboBoxEvent不必从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.如果你想在选中一个新item的时候得到QComboBox所有可能的信息那么最好在getSectionShape中得到QComboBox,为此有以下可能性。

2.1将comboBoxEvent设为QObject,这样就可以在slot中使用sender()方法获取QComboBox:

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 通过functools.partial传递QComboBox:

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. 通过 lambda 传递 QComboBox
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))
# ...