在主 window 中显示一个对话框

Display a dialog within the main window

下面的代码在按下 Hello! 时创建一个空对话框:

from PyQt5 import QtWidgets, QtCore

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        w = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()
        w.setLayout(layout)
        self.setCentralWidget(w)

        toyButton = QtWidgets.QPushButton("Hello!")
        layout.addWidget(toyButton)
        toyButton.clicked.connect(self.showdialog)

    def showdialog(self):
        d = QtWidgets.QDialog()
        d.setWindowTitle("Dialog")
        d.setWindowModality(QtCore.Qt.WindowModal)
        d.exec_()

if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    window = MainWindow()
    window.show()
    app.exec_()

如何强制对话框出现在 主 window 中,而不是让它作为一个独立的 window 浮动?

您只需为对话框提供一个 parent 小部件:d = QtWidgets.QDialog(self.centralWidget())self 也是有效的 parent;选择你最喜欢的!

您还可以将 d 添加到布局中:self.centralWidget().layout().addWidget(d); 虽然这第二个不尊重你的模态+执行。

这是比较两种方法的完整代码:

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        w = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()
        w.setLayout(layout)
        self.setCentralWidget(w)

        toyButton = QtWidgets.QPushButton("Hello!")
        layout.addWidget(toyButton)
        toyButton.clicked.connect(self.showdialog)

        toyButton2 = QtWidgets.QPushButton("Hello2!")
        layout.addWidget(toyButton2)
        toyButton2.clicked.connect(self.showdialog2)

    def showdialog(self):
        d = QtWidgets.QDialog(self.centralWidget())
        d.setWindowTitle("Dialog")
        d.setWindowModality(QtCore.Qt.WindowModal)
        d.exec_()

    def showdialog2(self):
        d = QtWidgets.QDialog()
        d.setWindowTitle("Dialog2")   # window title won't be seen...
        d.setWindowModality(QtCore.Qt.WindowModal)
        QtWidgets.QPushButton('Dialog2', parent=d) # ... so we add a little something
        self.centralWidget().layout().addWidget(d)
        d.exec_()