如何从stackedLayout访问centralWidget中的小部件?

2024-09-30 10:34:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个QMainWindow文件控制器.py它在centralWidget和多个名为win0.py、win1.py、。。。具有嵌套在QstackedLayout中的不同布局。 现在我想启用/禁用控制器主窗口菜单栏中的按钮,并在centralWidget中获取一些变量/调用函数

这个例子是基于下面的问题,而不是我的答案:

Using QStackedWidget for multi-windowed PyQt application

How to make nested StackedLayouts in PyQt5?

最接近的问题是:

Setting up stateChanged signal in QStackedWidget, pyqt

但是他们都没有改变主窗口(控制器)上的项目,就像我尝试做的那样。有关详细信息,请参见代码。你知道吗

你知道吗控制器.py地址:

import sys

from PyQt5.QtWidgets import *
from PyQt5 import QtCore

from win0 import W0     # sample window
#from win1 import W1     # further windows
#from win2 import W2

class Controller (QMainWindow):
    def __init__(self, parent=None):
        #super(Controller, self).__init__(parent)
        QMainWindow.__init__(self, parent)
        # used variables
        self.winDict = {}
        self.v1 = " self.V1 in Controller"

        # create stack
        self.stackLayout = QStackedLayout ()

        # put stack on MainWindow
        self.MainWidget =QWidget()
        self.MainWidget.setLayout(self.stackLayout)
        self.setCentralWidget(self.MainWidget)
        self.init_MenuBar ()

        # add further layouts
        self.init_Windows()
        # swith to first layout
        self.activeWin = self.switchWin (0)

    def init_MenuBar(self):

        self.toolbarButton_file = QPushButton (self.tr ("File"))
        self.toolbarButton_0 = QPushButton (self.tr ("Win0"))
        self.toolbarButton_1 = QPushButton (self.tr ("Win1"))
        self.toolbarButton_2 = QPushButton (self.tr ("Win2"))

        toolbar = self.addToolBar ("Window Manager")
        toolbar.addWidget (self.toolbarButton_file)
        toolbar.addWidget (self.toolbarButton_0)
        toolbar.addWidget (self.toolbarButton_1)
        toolbar.addWidget (self.toolbarButton_2)
        toolbar.setMovable (False)

        self.toolbarButton_0.clicked.connect ( (lambda: self.switchWin (0)))
        self.toolbarButton_1.clicked.connect ((lambda: self.switchWin (1)))
        self.toolbarButton_2.clicked.connect ((lambda: self.switchWin (2)))
        self.toolbarButton_0.setCheckable (False)
        self.toolbarButton_1.setCheckable(False)
        self.toolbarButton_2.setCheckable(False)
        self.toolbarButton_0.setEnabled (True)
        self.toolbarButton_1.setEnabled (True)
        self.toolbarButton_2.setEnabled (True)

    def init_Windows(self):
        self.switchWin(0, True)
        self.switchWin(1, True)
        self.switchWin(2, True)


    def switchWin(self, id=0, initonly = False):
        print ("-> switchWin:", id)
        if id not in self.winDict.keys ():
            if id == 0:
                self.winDict[id] = W0 ()
            #elif id == 1:
            #    self.winDict[id] = W1 ()
            #elif id == 2:
            #    self.winDict[id] = W2 ()
            self.stackLayout.addWidget (self.winDict[id])

        if not initonly:
            self.stackLayout.setCurrentIndex (id)
        Window = self.winDict[id]
        return Window

    def list_v1(self):
        print("-> Controller.list_V1")
        print("V1:", self.v1)

def main():
    App = QApplication(sys.argv)
    ProgramWindow = Controller()
    ProgramWindow.show()
    App.exec_()

if __name__ == "__main__":
    main()

win0.py(win1.py。。。相同的基础)

import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

class W0(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = self.init_UI()
        self.v1 ="Variable in W0"
        self.ui.pushButton.clicked.connect (self.pbClicked)

    def init_UI(self):
        mainForm = ("win0.ui")
        print ("mainForm:", mainForm)
        Widget = uic.loadUi (mainForm, self)
        return Widget

    def pbClicked(self):
        print ("-> win0.pbClicked")
        self.parent().toolbarButton_0.setEnabled (False)       # There is the question
                                                               # How to access widgets and functions, variables on the
                                                               # centralWidget or MainWindow of Controller.py. I want to en/disable button in the menuBar e.g.

if __name__ == "__main__":
    App = QApplication (sys.argv)
    ProgramWindow = W0()
    ProgramWindow.show ()
    App.exec_ ()

win0.ui(在win1.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>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>0</y>
      <width>43</width>
      <height>13</height>
     </rect>
    </property>
    <property name="text">
     <string>Win 0</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>60</x>
      <y>0</y>
      <width>80</width>
      <height>20</height>
     </rect>
    </property>
    <property name="text">
     <string>PushButton</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton_0">
    <property name="geometry">
     <rect>
      <x>180</x>
      <y>0</y>
      <width>80</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>PushButton_0</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>20</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

使用pyqt5和python3.7。我试着用 import from Controller这会导致无限循环和self.parent().toolbarButton_0.setEnabled (False) 导致
AttributeError: 'QWidget' object has no attribute 'toolbarButton_0'


Tags: namefromrectimportselfidinitdef
1条回答
网友
1楼 · 发布于 2024-09-30 10:34:46

与直接从W0操作Controller小部件不同,您可以使用信号和插槽进行通信。例如,在W0中,您可以执行以下操作

class W0(QMainWindow):
    button_clicked = QtCore.pyqtSignal()

    def __init__(self):
        ...
        self.ui.pushButton.clicked.connect(self.pbClicked)

    ....

    def pbClicked(self):
        print (f"-> win{self.id}.pbClicked")
        self.button_clicked.emit()

Controller

class Controller(QMainWindow):

    ....

    def switchWin(self, id=0, initonly = False):
        print ("-> switchWin:", id)
        if id not in self.winDict.keys ():
            if id == 0:
                self.winDict[id] = W0 ()
                self.winDict[id].button_clicked.connect(self.W0_button_clicked)
        ....

    def W0_button_clicked(self):
        self.toolbarButton_0.setEnabled (False)

当然,在Controller.SwitchWin中,您可以直接连接到信号self.winDict[id].ui.pushButton.clicked,但是在W0中创建一个单独的信号并在单击按钮时发出该信号的好处是,您可以更改W0的Gui,而无需重写Controller中的信号槽连接。此外,如果需要,您可以通过指定信号的输入参数来使用该信号发送附加数据。你知道吗

相关问题 更多 >

    热门问题