从另一个文件中的按钮切换 QStackedWidget 中的小部件

Switch widget in QStackWidget from a button in another file

我有两个py文件。一个是主 window 里面有一个 QStackedWidget,setCurrentWidget 是根据条件设置的。另一个文件有一个小部件,它会动态添加到堆叠小部件中,并在单击主 window 中的按钮时设置为当前小部件。 第二个文件中的小部件有一个对话框,其中有一个按钮。我想要做的是,在单击对话框内的按钮时,应关闭对话框并根据条件设置 setCurrentWidget 并将小部件从堆叠的小部件中删除。

这是我试过的方法:

mainwindow.py

import sys
import os
import pathlib
from PySide2.QtWidgets import *
from PySide2 import *
from PySide2.QtCore import *
from PySide2.QtGui import *


list1 = ["item1", "item2", "item3"]


class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.resize(400, 300)

        self.toolbar = QWidget()
        self.toolbar.setFixedHeight(30)
        self.toolbar.setStyleSheet("background: grey;")

        self.button = QPushButton("Click here!")
        t_layout = QHBoxLayout()
        t_layout.setMargin(0)
        t_layout.addWidget(self.button)
        self.toolbar.setLayout(t_layout)

        self.p1_label = QLabel("Such empty!")
        self.p1_label.setStyleSheet("font-size: 30px;")
        self.p1_label.setAlignment(Qt.AlignCenter)

        self.p2_widget = QWidget()
        self.p2_widget.setStyleSheet("background: orange;")

        self.sw = QStackedWidget()
        self.sw.addWidget(self.p1_label)
        self.sw.addWidget(self.p2_widget)

        if not list1:
            self.sw.setCurrentWidget(self.p1_label)
        else:
           self.sw.setCurrentWidget(self.p2_widget)

        self.mw_layout = QVBoxLayout()
        self.mw_layout.addWidget(self.toolbar)
        self.mw_layout.addWidget(self.sw)
        self.setLayout(self.mw_layout)

        def switch_widget():
            import widget_test
            p3 = widget_test.widget()
            self.sw.addWidget(p3)
            self.sw.setCurrentWidget(p3)

        self.button.clicked.connect(switch_widget)

    def switch_back(self):
        import widget_test
        p3 = widget_test.widget()
        mwin = MainWindow()
        sw_ = mwin.sw
        sw_.removeWidget(p3)
        p1 = mwin.p1_label
        p2 = mwin.p2_widget
        if not list1:
            sw_.setCurrentWidget(p1)
        else:
            sw_.setCurrentWidget(p2)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

widget.py

import sys
import os  
import pathlib
import datetime
from PySide2.QtWidgets import *
from PySide2 import *
from PySide2.QtCore import *
from PySide2.QtGui import *


class widget(QWidget):
    def __init__(self):
        super(widget, self).__init__()
        self.setStyleSheet("background: teal;")

        widget_label = QLabel("fluid dynamics is cool")
        show_pop_up = QPushButton("show pop up")

        pop_up = QDialog(self)
        pop_up_label = QLabel("click below to, hopefully, get outta here")
        get_outta_here = QPushButton("get outta here")
        pop_up_layout = QVBoxLayout()
        pop_up_layout.addWidget(pop_up_label)
        pop_up_layout.addWidget(get_outta_here)
        pop_up.setLayout(pop_up_layout)

        def show_popup():
            pop_up.show()

        def get_out():
            from main_test import MainWindow
            MainWindow.switch_back(self)
            pop_up.reject()

        get_outta_here.clicked.connect(get_out)

        show_pop_up.clicked.connect(show_popup)

        widget_layout = QVBoxLayout()
        widget_layout.addWidget(widget_label)
        widget_layout.addWidget(show_pop_up)
        self.setLayout(widget_layout)

我可以将代码合并在一起并使其工作,但我正在努力保持目录清洁。

这里发生了很多事情,但让我们分解一下。

主要问题似乎是模块之间的杂耍。尽管来回导入模块看起来很有吸引力,但实际上并没有用。您需要寻找的是可以使用的内置 Signals module

另一个更大的问题是您正在重新分配某些属性,尽管您确实不应该这样做。您还应该重新访问用于分配 .setCurrentWidget 的条件。当前条件显示为 if list1 doesn't exist, do this. Else, do the other。此外,switch_widget 应该在 def __init__(self):.

之外

我重写了代码的某些部分以使其与信号一起工作,作为您的示例。

mainwindow.py

import sys
import os
import pathlib
from PySide2.QtWidgets import *
from PySide2 import *
from PySide2.QtCore import *
from PySide2.QtGui import *
from widget_test import widget



list1 = ["item1", "item2", "item3"]


class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.resize(400, 300)

        self.toolbar = QWidget()
        self.toolbar.setFixedHeight(30)
        self.toolbar.setStyleSheet("background: grey;")

        self.button = QPushButton("Click here!")
        t_layout = QHBoxLayout()
        t_layout.setMargin(0)
        t_layout.addWidget(self.button)
        self.toolbar.setLayout(t_layout)

        self.p1_label = QLabel("Such empty!")
        self.p1_label.setStyleSheet("font-size: 30px;")
        self.p1_label.setAlignment(Qt.AlignCenter)

        self.p2_widget = QWidget()
        self.p2_widget.setStyleSheet("background: orange;")

        self.p3 = None

        self.sw = QStackedWidget()
        self.sw.addWidget(self.p1_label)
        self.sw.addWidget(self.p2_widget)

        if not list1:
            self.sw.setCurrentWidget(self.p1_label)
        else:
           self.sw.setCurrentWidget(self.p2_widget)

        self.mw_layout = QVBoxLayout()
        self.mw_layout.addWidget(self.toolbar)
        self.mw_layout.addWidget(self.sw)
        self.setLayout(self.mw_layout)

        self.button.clicked.connect(self.switch_widget)

    def switch_widget(self):
        self.p3 = widget()
        self.p3.update_signal.connect(self.switch_back)
        self.sw.addWidget(self.p3)
        self.sw.setCurrentWidget(self.p3)


    def switch_back(self):
        self.sw.removeWidget(self.p3)
        if list1:
            self.sw.setCurrentWidget(self.p1_label)
        else:
            self.sw.setCurrentWidget(self.p2_widget)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

widget.py

import sys
import os
import pathlib
import datetime
from PySide2.QtWidgets import *
from PySide2 import *
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtCore import Signal


class widget(QWidget):
    update_signal = Signal()
    def __init__(self):
        super(widget, self).__init__()
        self.setStyleSheet("background: teal;")

        widget_label = QLabel("fluid dynamics is cool")
        show_pop_up = QPushButton("show pop up")

        pop_up = QDialog(self)
        pop_up_label = QLabel("click below to, hopefully, get outta here")
        get_outta_here = QPushButton("get outta here")
        pop_up_layout = QVBoxLayout()
        pop_up_layout.addWidget(pop_up_label)
        pop_up_layout.addWidget(get_outta_here)
        pop_up.setLayout(pop_up_layout)

        def show_popup():
            pop_up.show()

        def get_out():
            self.update_signal.emit()
            pop_up.reject()

        get_outta_here.clicked.connect(get_out)

        show_pop_up.clicked.connect(show_popup)

        widget_layout = QVBoxLayout()
        widget_layout.addWidget(widget_label)
        widget_layout.addWidget(show_pop_up)
        self.setLayout(widget_layout)

最后,检查 Python coding conventions 的命名和其他 "minor" 详细信息。