在单独的 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))
# ...
- 通过 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))
# ...
我无法从 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))
# ...
- 通过 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))
# ...