【问题标题】:Sticky QWidget to right screen border when hidden QWidget and adjustSize隐藏 QWidget 和 adjustSize 时将 QWidget 粘贴到右屏幕边框
【发布时间】:2017-10-16 00:34:34
【问题描述】:

我正在尝试使 QWidget 贴在屏幕右边框上,并在左侧显示/隐藏另一个 QWidget。我们的目标是在最终获得类似的东西:

----------------------------------
|   Rest of screen    |          |
|                     |  Dock    |
|                     |  QWdiget |
|                     |          |
|                     |   button |
|                     |          |
|                     |          |
----------------------------------

点击按钮后:

----------------------------------
|  Panel QWidget      |          |
|                     |  Dock    |
|                     |  QWdiget |
|                     |          |
|                     |   button |
|                     |          |
|                     |          |
----------------------------------

到目前为止一切都很好,但是只要我按下按钮,QWidget“停靠”就会移动并且不想停留在屏幕边缘。如果我试图把它放回正确的地方,它就不是在正确的地方,给我这样的东西:

----------------------------------
|  Rest of screen     |          |
|  when Panel Qwidget | ---------| 
|  is hidden          | |  Dock  |
|                     | |QWdiget |
|                     | |        |
|                     | | button |
|                     | |        |
|                     | |        |
----------------------------------

有没有办法实现我想要的?保持 QWidget Dock 正确而不移动并仅使用按钮显示 QWidget 面板以占据屏幕的其余部分?我试图“玩”QSizePolicy,但没有成功。

这是我的示例代码:

from PyQt5.Qt import QWidget, QApplication, QLabel, QHBoxLayout, QPushButton, QSizePolicy


class DockWidget(QWidget):

    def __init__(self):
        super(DockWidget, self).__init__()
        self.button = QPushButton('Panel')

    def initialize(self):
        """

        :return:
        """

        layout = QHBoxLayout()
        self.setLayout(layout)

        label = QLabel('Dock')
        layout.addWidget(label)

        layout.addWidget(self.button)

class PanelWidget(QWidget):

    def initialize(self):
        """

        :return:
        """

        layout = QHBoxLayout()
        self.setLayout(layout)

        label = QLabel('Panel')
        layout.addWidget(label)

        # self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)


class MainWidget(QWidget):

    def __init__(self):
        super(MainWidget, self).__init__()
        self.panel = PanelWidget()
        self.dock = DockWidget()
        self.pos_x = 0

    def initialize(self):
        """

        :return:
        """

        layout = QHBoxLayout()
        self.setLayout(layout)

        self.panel.initialize()
        self.panel.hide()

        desktop = QApplication.desktop().availableGeometry()
        x_size = desktop.width() * 0.2
        y_size = desktop.height()

        pos_x = desktop.width() - self.width() * 0.5

        self.dock.setFixedSize(x_size, y_size)
        self.move(pos_x, 0)
        self.pos_x = pos_x

        self.dock.initialize()
        self.panel.resize(desktop.width() - x_size, desktop.height() - y_size)

        layout.addWidget(self.panel)
        layout.addWidget(self.dock)

        self.dock.button.clicked.connect(self.expand_panel)
        self.dock.show()

        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)

    def expand_panel(self):
        """

        :return:
        """

        if self.panel.isHidden():

            self.panel.show()
        else:
            # self.move(self.pos_x, 0)
            self.panel.hide()
            self.adjustSize()


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)

    main = MainWidget()
    main.initialize()

    main.show()

    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyqt5


    【解决方案1】:

    您需要移动和调整主窗口的大小,而不是它包含的小部件。还。您当前的代码没有考虑窗口框架,这意味着它最终可能会被调整为比桌面更大,或者部分位于屏幕外。

    如果您的应用程序需要在 X11(即大多数 Linux 系统)上运行,则要使其正常运行需要克服几个困难(有关详细信息,请参阅 Qt 文档中的X11 peculiarities)。主要是 X11 窗口管理器在调用show() 之后异步添加窗口框架。这意味着在您首次创建和初始化窗口时无法计算正确的几何图形。此外,如果您稍后需要查询框架几何形状,也无法保证准确报告。因此,解决这些问题需要一点技巧。

    下面的脚本尝试根据您的原始示例执行此操作。它在我的系统上运行良好(Linux,带有 Openbox 窗口管理器),但它很有可能在你的系统上运行不一样。单次计时器用于在屏幕上显示窗口后重新调整几何图形 - 我为此使用了最短的延迟,但您可能需要让它更长一点。这种延迟在展开面板时可能会产生轻微的闪烁,但我认为这是不可避免的。

    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    
    class DockWidget(QWidget):
        def __init__(self):
            super(DockWidget, self).__init__()
            self.button = QPushButton('Panel')
    
        def initialize(self):
            layout = QHBoxLayout()
            self.setLayout(layout)
            label = QLabel('Dock')
            layout.addWidget(label)
            layout.addWidget(self.button)
    
    class PanelWidget(QWidget):
        def initialize(self):
            layout = QHBoxLayout()
            self.setLayout(layout)
            label = QLabel('Panel')
            layout.addWidget(label)
    
    class MainWidget(QWidget):
        def __init__(self):
            super(MainWidget, self).__init__()
            self.panel = PanelWidget()
            self.dock = DockWidget()
    
        def initialize(self):
            layout = QHBoxLayout()
            self.setLayout(layout)
            self.dock.initialize()
            self.panel.initialize()
            layout.addWidget(self.panel)
            layout.addWidget(self.dock)
            self.dock.button.clicked.connect(self.expand_panel)
            self.panel.hide()
            self.initializeGeometry(0.2)
            self.dock.setMaximumWidth(self.width())
    
        def initializeGeometry(self, proportion, adjust=True):
            desktop = QApplication.desktop().availableGeometry()
            width = int(desktop.width() * proportion)
            height = desktop.height()
            client = self.geometry()
            frame = self.frameGeometry()
            xoffset = frame.width() - client.width()
            yoffset = frame.height() - client.height()
            self.move(desktop.width() - width, 0)
            self.resize(width - xoffset, height - yoffset)
            self.show()
            if adjust:
                QTimer.singleShot(
                    50, lambda: self.initializeGeometry(proportion, False))
    
        def expand_panel(self):
            if self.panel.isHidden():
                self.panel.show()
                self.initializeGeometry(1)
            else:
                self.panel.hide()
                self.initializeGeometry(0.2)
    
    if __name__ == '__main__':
    
        import sys
        app = QApplication(sys.argv)
        main = MainWidget()
        main.initialize()
        app.exec_()
    

    【讨论】:

    • 经过多次测试,我认为您的答案是正确的。我必须在 Ubuntu(或一般的 Linux)下使用窗口框架来调整大小。感谢您指出这一点。
    猜你喜欢
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多