My Design

我正在try 创建一个动态自定义对话框类.它以central小部件作为参数,centralwidget将是这个定制对话框的主要小部件.(用于动态)

当它出现时,会使背景变暗.

重要的是将自己添加到主窗口的布局中,这样当主窗口的大小/位置发生变化时,它可以自动调整自己.

我可以通过挂钩resizeEvent/moveEvent来实现这一点,但我正在寻找更好的方式来实现这一点.如果我把这个自定义对话框添加到主窗口的布局中,效果会更好.

谢谢

推荐答案

创建一个子小部件,该小部件根据窗口的当前内容绘制,并在resizeEvent()覆盖中调整大小,这绝对不是问题.事实上,每次使用布局管理器的小部件调整大小时,Qt实际上就是这么做的.这种方法的好处是,您可以完全"覆盖"窗口的all个内容,包括菜单栏、状态栏和任何停靠/工具栏.

如果您仍然希望它们可用,并且只希望覆盖主小部件,那么您可以通过将"覆盖"设置为主小部件本身的子级,而不是将窗口用作父级来实现.

另一种 Select 是使用QStackedWidget作为中心小部件,并将布局(这是一个QStackedLayout)设置为使用StackAll stackingMode,这将允许您显示叠加布局的所有"页面".

请注意,这种方法有一个重要的缺点:需要注意选项卡焦点.由于显示并启用了所有小部件(包括属于另一个"页面"的小部件),通过选项卡更改焦点将允许将焦点更改为不属于"对话框"的小部件.

我给大家留下一个基本的例子,中心小部件是一个QTableWidget,每当双击一个项目时,它都会显示"弹出窗口".

请仔细研究它并试着理解它的作用.

from PyQt5 import QtCore, QtWidgets


class Container(QtWidgets.QWidget):
    def showEvent(self, event):
        if not event.spontaneous():
            self.setFocus()
            # certain widgets might want to keep focus on tab
            # so we delay the focusNextChild
            QtCore.QTimer.singleShot(0, self.focusNextChild)

    def focusNextPrevChild(self, isNext):
        # keep tab focus on this widget
        super().focusNextPrevChild(isNext)
        return self.isAncestorOf(QtWidgets.QApplication.focusWidget())

    def paintEvent(self, event):
        # stylesheets set on QWidget subclasses need this
        qp = QtWidgets.QStylePainter(self)
        opt = QtWidgets.QStyleOption()
        opt.initFrom(self)
        qp.drawPrimitive(QtWidgets.QStyle.PE_Widget, opt)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.menuBar().addMenu('Test').addAction('Action')
        self.stack = QtWidgets.QStackedWidget(self)
        self.setCentralWidget(self.stack)
        self.stack.layout().setStackingMode(QtWidgets.QStackedLayout.StackAll)

        table = QtWidgets.QTableWidget(20, 30)
        self.stack.addWidget(table)

        table.cellDoubleClicked.connect(self.showDialog)

        self.resize(QtWidgets.QApplication.primaryScreen().size() * 2 / 3)

    def showDialog(self, row, column):
        background = QtWidgets.QWidget(objectName='background')
        background.setStyleSheet('''
            #background {
                background: rgba(64, 64, 64, 64);
            }
            Container {
                background: palette(window);
                border: 1px outset palette(window);
                border-radius: 5px;
            }
        ''')
        backLayout = QtWidgets.QVBoxLayout(background)
        
        container = Container()
        backLayout.addWidget(container, alignment=QtCore.Qt.AlignCenter)
        container.setAutoFillBackground(True)
        layout = QtWidgets.QVBoxLayout(container)
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(20)

        font = self.font()
        font.setPointSize(font.pointSize() * 3)
        layout.addWidget(QtWidgets.QLabel(
            'Hello!', font=font, alignment=QtCore.Qt.AlignCenter))
        layout.addWidget(QtWidgets.QLabel(
            'You doubleclicked cell {}, {}'.format(row + 1, column + 1)))
        button = QtWidgets.QPushButton('Close')
        layout.addWidget(button)

        self.centralWidget().addWidget(background)
        self.centralWidget().setCurrentWidget(background)

        # Important! you must always delete the widget when you don't need it
        # anymore. Alternatively, hide it if you want to reuse it again later
        button.clicked.connect(background.deleteLater)


app = QtWidgets.QApplication([])
win = MainWindow()
win.show()
app.exec()

Python相关问答推荐

使用plotnine和Python构建地块

使用SciPy进行曲线匹配未能给出正确的匹配

处理(潜在)不断增长的任务队列的并行/并行方法

可变参数数量的重载类型(args或kwargs)

如何在solve()之后获得症状上的等式的值

运输问题分支定界法&

将9个3x3矩阵按特定顺序排列成9x9矩阵

在单个对象中解析多个Python数据帧

Tkinter菜单自发添加额外项目

为什么numpy. vectorize调用vectorized函数的次数比vector中的元素要多?

Maya Python脚本将纹理应用于所有对象,而不是选定对象

matplotlib图中的复杂箭头形状

python—telegraph—bot send_voice发送空文件

如何获取Python synsets列表的第一个内容?

基于多个数组的多个条件将值添加到numpy数组

Flask运行时无法在Python中打印到控制台

裁剪数字.nd数组引发-ValueError:无法将空图像写入JPEG

如何根据一定条件生成段id

操作布尔值的Series时出现索引问题

将字节序列解码为Unicode字符串