如何在 PyQt 中连接三个或更多 windows

How do I connect three or more windows in PyQt

我有一个复杂的程序,我需要在其中连接多个 windows。不幸的是,我似乎没有完全理解执行此操作所必需的 concept/steps,因此如果有人能很好地解释 steps/process 则加分。在我当前的程序中,我有一个项目列表。一旦我 select 通过将它们移动到正确的列表小部件,我需要它们转到第三个 window。第三个 window 应通过单击第二个 window 上的点来激活。程序运行并正确显示第二个 window,但点按钮的 signal/slot 连接不起作用。但是,其余代码可以正常工作,因为如果我切换工具包以显示第三个 window,该部分将按预期执行。我的代码在下面,同样,没有返回任何错误,但是单击第二个 window 上的点按钮什么也没做。

还有一个问题 - 我是在第二个 class 中实例化第三个 window,还是仅在主 window 中实例化?再次,努力完全理解这个过程,我将需要多次这样做。

from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QListWidget, QLineEdit, QTextEdit, QGridLayout, QHBoxLayout, QVBoxLayout, QSizePolicy, QFileDialog, QTabWidget, QCheckBox
import PyQt5.QtGui as qtg
import glob
import os
from PyQt5.QtCore import Qt, QSettings
import inspect
from PyQt5 import QtCore
import pandas as pd 
import pathlib
import pyreadstat
import json


class ThirdWindow(QWidget):
    def __init__(self):
        super().__init__()
        
        
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        self.allVariables = QListWidget()
        self.variablesSelected = QListWidget()
        #self.allVariables.insertItem(0, 'Hello')
        self.layout.addWidget(self.allVariables, 1,0)
        self.layout.addWidget(self.variablesSelected, 1, 1)
        
    def setItems(self, items):
        self.allVariables.clear()
        for item in items:
            self.allVariables.addItem(item)
     
    
     
class SecondWindow(QWidget):
    def __init__(self):
        super().__init__()
        
        ##not sure if I am supposed to instantiate this here or only in the main window class
        self.thirdWindow = ThirdWindow()
        
    
        self.layout = QGridLayout(self)
        self.by = QLabel("By")
        self.byVariables = QLineEdit()
        self.byButton = QPushButton("...")
        self.layout.addWidget(self.by, 1, 0)
        self.layout.addWidget(self.byVariables, 2, 0)
        self.layout.addWidget(self.byButton, 2, 1)
        
       
    def seconddWindowConnections(self):
        self.byButton.clicked.connect(self.show_third_window)
        #self.buttons['Toolkit'].clicked.connect(self.show_new_window)   
        
    def show_third_window(self):
        self.thirdWindow.show()
        
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        # Add a title
        self.setWindowTitle("GUI Querying Program")

        self.layout = QHBoxLayout()
        self.setLayout(self.layout)
        self.initUI()
        self.setButtonConnections()
        
        self.sw = SecondWindow()
        self.tw = ThirdWindow()
        

    def initUI(self):
        subLayouts = {}

        subLayouts['LeftColumn'] = QGridLayout()
    
        self.layout.addLayout(subLayouts['LeftColumn'],1)
        
        # Buttons
        self.buttons = {}
        self.buttons['addVariable'] = QPushButton('>')
        self.buttons['removeVariable'] = QPushButton('<')
        self.buttons['Toolkit'] = QPushButton('Toolkit')
        
        
        self.variables = QListWidget()
        self.selectedVariables = QListWidget()
        
        subLayouts['LeftColumn'].addWidget(self.variables, 7,0,4,1)
        subLayouts['LeftColumn'].addWidget(self.selectedVariables, 7,1,4,1)
        subLayouts['LeftColumn'].addWidget(self.buttons['addVariable'], 10,0,1,1)
        subLayouts['LeftColumn'].addWidget(self.buttons['removeVariable'], 10,1,1,1)
        subLayouts['LeftColumn'].addWidget(self.buttons['Toolkit'], 11,1,1,1)
        
        names = ['apple', 'banana', 'Cherry']
        self.variables.insertItems(0, names)
        
    def setButtonConnections(self):
        self.buttons['addVariable'].clicked.connect(self.add_variable)
        self.buttons['Toolkit'].clicked.connect(self.show_new_window)   
        self.buttons['Toolkit'].clicked.connect(self.add_selected_variables)
        
    def add_variable(self):
        for item in self.variables.selectedItems():
            self.selectedVariables.addItem(item.clone())

    def show_new_window(self):
        self.sw.show()
        
    def add_selected_variables(self):
        items = []
        for i in range(self.selectedVariables.count()):
            items.append(self.selectedVariables.item(i).clone())
        self.tw.setItems(items)


if __name__ == "__main__":
    import sys
    app = QApplication([])
    mw = MainWindow()
    mw.show()
    app.exec()

您的代码的主要问题是 secondWindowConnections 从未被调用,因此该按钮实际上什么都不做。我更正了它并修复了我在下面的示例中发现的其他一些问题。我遗漏了我没有做任何更改的位,我所做的所有更改我都做了内联注释来解释它们:

class SecondWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.thirdWindow = None  # dont initialize until neccessary
        self.thirdWindowItems = []
        self.layout = QGridLayout(self)
        self.by = QLabel("By")
        self.byVariables = QLineEdit()
        self.byButton = QPushButton("...")
        self.layout.addWidget(self.by, 1, 0)
        self.layout.addWidget(self.byVariables, 2, 0)
        self.layout.addWidget(self.byButton, 2, 1)
        self.secondWindowConnections()  #  Run this to setup the
                                       #  signal for the third window.
    def secondWindowConnections(self):   # this had a typo
        self.byButton.clicked.connect(self.show_third_window)

    def show_third_window(self):
        if self.thirdWindow is None:           # if window has been created yet
            self.thirdWindow = ThirdWindow()   # create window
        if not self.thirdWindow.isVisible():   # if window is showing
            self.thirdWindow.show()            # show window
        self.thirdWindow.setItems(self.thirdWindowItems)  # send items to window

    def send_items(self, items):       # this is to collect the variable that
        self.thirdWindowItems = items  # move to the third window

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        # Add a title
        self.setWindowTitle("GUI Querying Program")
        self.layout = QHBoxLayout()
        self.setLayout(self.layout)
        self.initUI()
        self.setButtonConnections()
        self.sw = None    # dont initialize until neccessary.

    def initUI(self):
        subLayouts = {}
        subLayouts['LeftColumn'] = QGridLayout()
        self.layout.addLayout(subLayouts['LeftColumn'],1)
        self.buttons = {}
        self.buttons['addVariable'] = QPushButton('>')
        self.buttons['removeVariable'] = QPushButton('<')
        self.buttons['Toolkit'] = QPushButton('Toolkit')
        self.variables = QListWidget()
        self.selectedVariables = QListWidget()
        subLayouts['LeftColumn'].addWidget(self.variables, 7,0,4,1)
        subLayouts['LeftColumn'].addWidget(self.selectedVariables, 7,1,4,1)
        subLayouts['LeftColumn'].addWidget(self.buttons['addVariable'], 10,0,1,1)
        subLayouts['LeftColumn'].addWidget(self.buttons['removeVariable'], 10,1,1,1)
        subLayouts['LeftColumn'].addWidget(self.buttons['Toolkit'], 11,1,1,1)
        names = ['apple', 'banana', 'Cherry']
        self.variables.insertItems(0, names)

    def setButtonConnections(self):
        self.buttons['addVariable'].clicked.connect(self.add_variable)
        self.buttons['Toolkit'].clicked.connect(self.show_new_window)
        # self.buttons['Toolkit'].clicked.connect(self.add_selected_variables)
        # only use one connnect slot

    def add_variable(self):
        for item in self.variables.selectedItems():
            self.selectedVariables.addItem(item.clone())

    def show_new_window(self):     
        if self.sw is None:   #  check if window has been constructed
            self.sw = SecondWindow()  # construct window
        if not self.sw.isVisible():    #  If winow is not showing
            self.sw.show()         #  show window
        self.sw.send_items(self.add_selected_variables())   # send selected 
                                                            # variables to second window

    def add_selected_variables(self):
        items = []
        for i in range(self.selectedVariables.count()):
            items.append(self.selectedVariables.item(i).clone())
        # self.tw.setItems(items) ...  self.tw doesnt exist so return them
        return items