Получить текст элемента QComboBox, вызванный событием в отдельном методе / функции класса - PullRequest
1 голос
/ 12 июня 2019

У меня проблемы с получением любой информации из QComboBox, кроме индекса в функции. В большинстве похожих примеров эта функция находится в том же классе, что и вызываемое событие. Я пытаюсь получить это из внешнего класса (и файла).

Структура папок, как указано в ответе здесь:

В 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 пуста (ожидается тип раздела), но мой индекс верен. Консоль печатает одну пустую и одну правильную строку. Что-то не работает с self.itemText (index) в форме getSectionShape EventMethods.py. Любая помощь приветствуется!

1 Ответ

1 голос
/ 12 июня 2019

Что означает self.itemText(index) в comboBoxEvent? , поскольку вы получаете текст текущего элемента comboBoxEvent. Есть ли у comboBoxEvent элементы? Нет, он пуст, элементы есть только у QComboBox, который находится в окне, comboBoxEvent не является 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. Если вы хотите получить всю возможную информацию о QComboBox при выборе нового элемента, тогда лучше получить QComboBox в getSectionShape, для этого есть следующие возможности.

2.1 Сделайте comboBoxEvent объектом QObject, чтобы QComboBox можно было получить с помощью метода sender () в слоте:

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 Пропустите QComboBox через 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. Пропустить 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))
# ...
...