Переключить виджет в QStackWidget с кнопки в другом файле - PullRequest
0 голосов
/ 29 мая 2020

У меня есть два файла py. У одного есть главное окно с QStackedWidget внутри, setCurrentWidget устанавливается в соответствии с условием. Другой файл имеет виджет, который динамически добавляется в составной виджет и устанавливается как текущий виджет при нажатии кнопки в главном окне. У виджета во втором файле есть диалог с кнопкой. Я пытаюсь сделать следующее: при нажатии кнопки внутри диалогового окна диалоговое окно должно быть закрыто, а 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)

Я мог бы объединить код вместе и заставить его работать, но я пытаюсь чтобы каталог был чистым.

1 Ответ

1 голос
/ 17 июня 2020

Здесь много чего происходит, но давайте остановимся на этом.

Основная проблема вроде жонглирования между модулями. Хотя импорт модулей туда и обратно может показаться привлекательным, на самом деле это не работает. Что вам нужно искать, так это встроенный модуль Signals , который вы можете использовать.

Другая более серьезная проблема заключается в том, что вы переназначаете некоторые атрибуты, хотя на самом деле этого делать не нужно. Вам также следует пересмотреть условие, которое вы используете для присвоения .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 соглашения о кодировании для именования и других «второстепенных» деталей.

...