PyQt: доступ к включенному состоянию из-за пределов класса виджета

Я создал интерфейс PyQt, и теперь я хочу переключать активное/неактивное состояние некоторых его виджетов или взаимодействовать с ними вне класса виджетов. У меня есть класс главного окна со всеми его виджетами и функциями вне класса - здесь подключен к buttton1. Моя цель в этом примере — включить button2, нажав button1.

В приведенном ниже коде я получаю сообщение об ошибке, что мой класс Ui_MainWindow не имеет атрибута button1.

Код:

from PyQt4 import QtCore, QtGui

def toggle():
     Ui_MainWindow.button2.setEnabled(True)

class Ui_MainWindow(object):
     def setupUi(self, MainWindow):
         MainWindow.setObjectName(_fromUtf8("MainWindow"))
         self.button1 = QtGui.QPushButton(self.centralwidget)
         self.button1.clicked.connect(toggle)
         self.button2 = QtGui.QPushButton(self.centralwidget)
         self.button2.setEnabled(False)
         QtCore.QMetaObject.connectSlotsByName(MainWindow)       

if __name__ == "__main__":

    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Пока не знаю, я избегал использования классов, потому что, честно говоря, они для меня очень абстрактны. Наверное, поэтому я терплю неудачу здесь. Я предполагаю, что неправильно обращаюсь к классу виджетов.

Я был бы признателен, если бы кто-то мог указать мне в правильном направлении. Я прочитал все ответы на подобные проблемы - но это не помогло мне прийти к решению.


person Esmi    schedule 06.11.2016    source источник


Ответы (1)


Я предполагаю, что вы разработали пользовательский интерфейс для своего примера в Qt Designer и преобразовали его в модуль Python, используя pyuic4. Что вам нужно сделать, так это импортировать этот модуль в ваш основной скрипт, а затем создать класс MainWindow, который загружает пользовательский интерфейс. Если вы все сделаете правильно, все виджеты из Qt Designer станут атрибутами этого класса. Затем вы можете добавить в класс методы, управляющие взаимодействием с виджетами.

Для начала заново сгенерируйте модуль пользовательского интерфейса и сохраните его как mainwindow_ui.py:

pyuic4 -o mainwindow_ui.py mainwindow.ui

Затем создайте основной скрипт следующим образом:

from PyQt4 import QtCore, QtGui
from mainwindow_ui import Ui_MainWindow

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self):
         super(MainWindow, self).__init__()
         self.setupUi(self)
         self.button1.clicked.connect(self.toggle)
         self.button2.setEnabled(False)

    def toggle(self):
         self.button2.setEnabled(not self.button2.isEnabled())

if __name__ == "__main__":

    import sys
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

Надеюсь, этот код достаточно прост и не требует пояснений. Однако, если вам нужны пошаговые руководства, я бы порекомендовал вам попробовать это:

PS: вот файл mainwindow.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>279</width>
    <height>90</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
     <widget class="QPushButton" name="button1">
      <property name="text">
       <string>Button 1</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="button2">
      <property name="text">
       <string>Button 2</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>279</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>
person ekhumoro    schedule 06.11.2016
comment
спасибо за вашу инструкцию. однако в вашем примере описывается обращение к функции в классе MainWindow. как бы вы сделали это из функции вне класса? - person Esmi; 06.11.2016
comment
@Эсми. Вы просили указать правильное направление, а это означает использование методов, а не внешних функций. Если вы попытаетесь сделать последнее, написание хорошего кода графического интерфейса может стать довольно трудным. У вас есть конкретная причина, по которой вы хотите делать что-то именно так? Какую проблему ты пытаешься решить? - person ekhumoro; 06.11.2016