显示当前小部件类之外的小部件
Posted
技术标签:
【中文标题】显示当前小部件类之外的小部件【英文标题】:Showing widget that is outside the current widgets class 【发布时间】:2021-01-22 23:12:31 【问题描述】:示例:
假设我有一个 MainWindow 小部件,在该类中,我实例化了另外两个小部件(小部件一和小部件二)。每个小部件将有一个按钮:小部件一和小部件二的 next 和 back 分别。第一个小部件是可见的,第二个是隐藏的。
我想在第一个小部件中调用一个函数,该函数将自身隐藏并显示第二个小部件。然后对第二个小部件进行同样的操作。
如果我在主窗口中放置函数并连接按钮,我可以这样做,但我想避免这种情况。我对信号和插槽没有很好的了解,不知道怎么做或任何其他策略,然后将所有逻辑放在主窗口中。
import sys
from PyQt5 import QtWidgets as qtw
class WidgetOne(qtw.QWidget):
def __init__(self):
super().__init__()
########
# initialization
########
self.layout = qtw.QVBoxLayout()
self.setLayout(self.layout)
########
# Buttons
########
self.next_button = qtw.QPushButton('Next')
self.next_button.clicked.connect(self.next_widget)
########
# Layout
########
self.layout.addWidget(self.next_button)
def next_widget(self):
self.hide()
# widget_two.show() # <--- This part won't work
class WidgetTwo(qtw.QWidget):
def __init__(self):
super().__init__()
########
# initialization
########
self.layout = qtw.QVBoxLayout()
self.setLayout(self.layout)
########
# Buttons
########
self.back_button = qtw.QPushButton('Back')
self.back_button.clicked.connect(self.back_to_first_widget)
########
# Layout
########
self.layout.addWidget(self.back_button)
self.hide()
def back_to_first_widget(self):
self.hide()
# widget_one.show() # This part won't work
class MainWindow(qtw.QWidget):
def __init__(self):
super().__init__()
########
# initialization
########
self.layout = qtw.QVBoxLayout()
self.setLayout(self.layout)
self.widget_one = WidgetOne()
self.widget_two = WidgetTwo()
########
# Layout
########
self.layout.addWidget(self.widget_one)
self.layout.addWidget(self.widget_two)
self.setWindowTitle("Title")
self.show()
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
mw = MainWindow()
sys.exit(app.exec())
【问题讨论】:
你已经看过QStackedWidget
了吗?它是一个始终显示一个小部件的容器,将其隐藏在子级之上。它还具有确保适合所有小部件的布局的好处。
@ypnos 我认为 QStackedWidget 非常适合我想做的事情。谢谢
【参考方案1】:
您必须建立可以访问两个对象(发送方和接收方)的连接。
import sys
from PyQt5 import QtWidgets as qtw
class WidgetOne(qtw.QWidget):
def __init__(self):
super().__init__()
self.next_button = qtw.QPushButton("Next")
self.next_button.clicked.connect(self.hide)
layout = qtw.QVBoxLayout(self)
layout.addWidget(self.next_button)
class WidgetTwo(qtw.QWidget):
def __init__(self):
super().__init__()
self.back_button = qtw.QPushButton("Back")
self.back_button.clicked.connect(self.hide)
layout = qtw.QVBoxLayout(self)
layout.addWidget(self.back_button)
self.hide()
class MainWindow(qtw.QWidget):
def __init__(self):
super().__init__()
self.widget_one = WidgetOne()
self.widget_two = WidgetTwo()
self.widget_one.next_button.clicked.connect(self.widget_two.show)
self.widget_two.back_button.clicked.connect(self.widget_one.show)
layout = qtw.QVBoxLayout(self)
layout.addWidget(self.widget_one)
layout.addWidget(self.widget_two)
self.setWindowTitle("Title")
if __name__ == "__main__":
app = qtw.QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec())
【讨论】:
不知道您可以将两种方法连接到一个事件...+1
来自我@eyllanesc
@JakubSzlaur 一个信号可以连接“n”个槽,一个槽可以连接“n”个信号,这是Qt的关键
从来不需要使用它,但老实说很高兴知道这一点!
@JakubSzlaur 另一方面,我看到在你的代码中你有self.next_button.clicked.connect(self.signal_next_widget.emit)
但没有必要使用发射,因为你也可以将一个信号连接到另一个信号,所以你可以用@替换它987654324@【参考方案2】:
为此使用QtCore.pyqtSignal
模块:
像这样创建模块(在构造函数之外):
class WidgetOne(qtw.QWidget):
signal_next_widget = QtCore.pyqtSignal() #Here
def __init__(self):
super().__init__()
...
然后在MainWindow
中连接那个信号:
self.widget_one.signal_next_widget.connect(self.next_widget)
self.widget_two.signal_back_to_first_widget.connect(self.back_to_first_widget)
将back_to_first_widget
和next_widget
方法添加到MainWindow
并相应地更改它们:
def back_to_first_widget(self):
self.widget_two.hide()
self.widget_one.show()
def next_widget(self):
self.widget_one.hide()
self.widget_two.show()
这是整个代码:
import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore
class WidgetOne(qtw.QWidget):
signal_next_widget = QtCore.pyqtSignal()
def __init__(self):
super().__init__()
########
# initialization
########
self.layout = qtw.QGridLayout()
self.setLayout(self.layout)
########
# Buttons
########
self.next_button = qtw.QPushButton('Next')
self.next_button.clicked.connect(self.signal_next_widget.emit)
########
# Layout
########
self.layout.addWidget(self.next_button)
class WidgetTwo(qtw.QWidget):
signal_back_to_first_widget = QtCore.pyqtSignal()
def __init__(self):
super().__init__()
########
# initialization
########
self.layout = qtw.QVBoxLayout()
self.setLayout(self.layout)
########
# Buttons
########
self.back_button = qtw.QPushButton('Back')
self.back_button.clicked.connect(self.signal_back_to_first_widget.emit)
########
# Layout
########
self.layout.addWidget(self.back_button)
self.hide()
class MainWindow(qtw.QWidget):
def __init__(self):
super().__init__()
########
# initialization
########
self.layout = qtw.QVBoxLayout()
self.setLayout(self.layout)
self.widget_one = WidgetOne()
self.widget_two = WidgetTwo()
self.widget_one.signal_next_widget.connect(self.next_widget)
self.widget_two.signal_back_to_first_widget.connect(self.back_to_first_widget)
########
# Layout
########
self.layout.addWidget(self.widget_one)
self.layout.addWidget(self.widget_two)
self.setWindowTitle("Title")
self.show()
def back_to_first_widget(self):
self.widget_two.hide()
self.widget_one.show()
def next_widget(self):
self.widget_one.hide()
self.widget_two.show()
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
mw = MainWindow()
sys.exit(app.exec())
【讨论】:
以上是关于显示当前小部件类之外的小部件的主要内容,如果未能解决你的问题,请参考以下文章