PyQt5:如何将子部件移动到主部件 window?
PyQt5: how to move sub widgets into main window?
此代码打开 3 个单独的 windows:
1) main window
2) widgetA
3) widgetB.
如何把代码写成把2和3移到1?
所以我们只有一个主要 window 和其中 2 个可以相互通信的小部件。此外,还有一个附加功能:我们如何编写一个函数,使其能够监听传入的数据,然后将其发送出去?
class mainwindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(mainwindow, self).__init__(parent)
self.button = QtWidgets.QPushButton("Click Me", self)
self.button.clicked.connect(self.on_button_clicked)
self.setCentralWidget(self.button)
self.widgetA = widgetA()
self.widgetB = widgetB()
self.widgetA.procStart.connect(self.widgetB.on_procStart)
self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.widgetA.show()
self.widgetB.show()
self.widgetA.raise_()
class widgetA(QtWidgets.QWidget):
procStart = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(widgetA, self).__init__(parent)
self.lineEdit = QtWidgets.QLineEdit(self)
self.lineEdit.setText("Hello!")
self.button = QtWidgets.QPushButton("Send Message to B", self)
self.button.clicked.connect(self.on_button_clicked)
self.layout = QtWidgets.QHBoxLayout(self)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.button)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.procStart.emit(self.lineEdit.text())
@QtCore.pyqtSlot(str)
def on_widgetB_procDone(self, message):
self.lineEdit.setText("From B: " + message)
self.raise_()
class widgetB(QtWidgets.QWidget):
procDone = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(widgetB, self).__init__(parent)
self.lineEdit = QtWidgets.QLineEdit(self)
self.button = QtWidgets.QPushButton("Send Message to A", self)
self.layout = QtWidgets.QHBoxLayout(self)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.button)
self.button.clicked.connect(self.on_button_clicked)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.procDone.emit(self.lineEdit.text())
@QtCore.pyqtSlot(str)
def on_procStart(self, message):
self.lineEdit.setText("From A: " + message)
self.raise_()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
main = mainwindow()
main.show()
sys.exit(app.exec_())
如果您需要将多个小部件显示到“顶层 window”(无论是 QWidget、QDialog 还是 QMainWindow),您需要创建一个 容器 小部件。
在您的情况下,您使用的是 QMainWindow,它是一种 非常 特殊的 QWidget,因为它有自己的(内部且几乎不可访问的)布局。通常在 QMainWindow 中显示的主要内容(除了它的菜单栏、状态栏、工具栏和停靠栏)称为“中央小部件”,而您将其设置为 QPushButton,因此没有 room 其他。
最常见和常规的方法是创建一个新的QWidget(这是一个空的widget,用作所有 Qt widgets的基础),为其设置布局并向其中添加实际的小部件:
class mainwindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(mainwindow, self).__init__(parent)
<b>container = QtWidgets.QWidget()
self.setCentralWidget(container)
# using a widget as an argument in a Qt layout constructor results in
# automatically setting the layout for that widget
layout = QtWidgets.QVBoxLayout(container)</b>
self.button = QtWidgets.QPushButton("Click Me", self)
self.button.clicked.connect(self.on_button_clicked)
self.widgetA = widgetA()
self.widgetB = widgetB()
<b>layout.addWidget(self.button)
layout.addWidget(self.widgetA)
layout.addWidget(self.widgetB)</b>
# ...
请注意,如果您使用的不是 QMainWindow,而是标准的 QWidget 或 QDialog,您显然不需要使用“中央小部件”,您只需在当前实例上创建一个新布局即可 (self
).
class SomeWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
layout = QtWidgets.QVBoxLayout(self)
# ...
此代码打开 3 个单独的 windows:
1) main window
2) widgetA
3) widgetB.
如何把代码写成把2和3移到1?
所以我们只有一个主要 window 和其中 2 个可以相互通信的小部件。此外,还有一个附加功能:我们如何编写一个函数,使其能够监听传入的数据,然后将其发送出去?
class mainwindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(mainwindow, self).__init__(parent)
self.button = QtWidgets.QPushButton("Click Me", self)
self.button.clicked.connect(self.on_button_clicked)
self.setCentralWidget(self.button)
self.widgetA = widgetA()
self.widgetB = widgetB()
self.widgetA.procStart.connect(self.widgetB.on_procStart)
self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.widgetA.show()
self.widgetB.show()
self.widgetA.raise_()
class widgetA(QtWidgets.QWidget):
procStart = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(widgetA, self).__init__(parent)
self.lineEdit = QtWidgets.QLineEdit(self)
self.lineEdit.setText("Hello!")
self.button = QtWidgets.QPushButton("Send Message to B", self)
self.button.clicked.connect(self.on_button_clicked)
self.layout = QtWidgets.QHBoxLayout(self)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.button)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.procStart.emit(self.lineEdit.text())
@QtCore.pyqtSlot(str)
def on_widgetB_procDone(self, message):
self.lineEdit.setText("From B: " + message)
self.raise_()
class widgetB(QtWidgets.QWidget):
procDone = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(widgetB, self).__init__(parent)
self.lineEdit = QtWidgets.QLineEdit(self)
self.button = QtWidgets.QPushButton("Send Message to A", self)
self.layout = QtWidgets.QHBoxLayout(self)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.button)
self.button.clicked.connect(self.on_button_clicked)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.procDone.emit(self.lineEdit.text())
@QtCore.pyqtSlot(str)
def on_procStart(self, message):
self.lineEdit.setText("From A: " + message)
self.raise_()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
main = mainwindow()
main.show()
sys.exit(app.exec_())
如果您需要将多个小部件显示到“顶层 window”(无论是 QWidget、QDialog 还是 QMainWindow),您需要创建一个 容器 小部件。
在您的情况下,您使用的是 QMainWindow,它是一种 非常 特殊的 QWidget,因为它有自己的(内部且几乎不可访问的)布局。通常在 QMainWindow 中显示的主要内容(除了它的菜单栏、状态栏、工具栏和停靠栏)称为“中央小部件”,而您将其设置为 QPushButton,因此没有 room 其他。
最常见和常规的方法是创建一个新的QWidget(这是一个空的widget,用作所有 Qt widgets的基础),为其设置布局并向其中添加实际的小部件:
class mainwindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(mainwindow, self).__init__(parent)
<b>container = QtWidgets.QWidget()
self.setCentralWidget(container)
# using a widget as an argument in a Qt layout constructor results in
# automatically setting the layout for that widget
layout = QtWidgets.QVBoxLayout(container)</b>
self.button = QtWidgets.QPushButton("Click Me", self)
self.button.clicked.connect(self.on_button_clicked)
self.widgetA = widgetA()
self.widgetB = widgetB()
<b>layout.addWidget(self.button)
layout.addWidget(self.widgetA)
layout.addWidget(self.widgetB)</b>
# ...
请注意,如果您使用的不是 QMainWindow,而是标准的 QWidget 或 QDialog,您显然不需要使用“中央小部件”,您只需在当前实例上创建一个新布局即可 (self
).
class SomeWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
layout = QtWidgets.QVBoxLayout(self)
# ...