PYQT QSplitter问题

发布于 2024-11-30 23:23:37 字数 691 浏览 1 评论 0原文

我使用 QSplitter,我发现小部件的最小宽度 分割器为 32 像素(高度为 23 像素)。有谁知道如何 更改此默认值。换句话说,您不能拖动拆分器以使其中之一 splitter中的widgets(假设splitter中有2个widget)会更少 宽度超过 32 像素。

代码:

class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):

        self.resize(400,400)

        m = QtGui.QSplitter(self)
        m.resize(200, 100)

        x = QtGui.QPushButton(m)
        x.setGeometry(0, 0, 100, 100)

        y = QtGui.QPushButton(m)
        y.setGeometry(0, 100, 100, 100)


        m.setSizes([20, 180])
        # this will show you that the width of x is 32 (it should be 20!)
        print x.width()

I use QSplitter and I found out that the minumum width of a widget in
the splitter is 32 pixels (and 23 pixels in height). Does anybody body knows how
to change this default. In other words, you can't drag the splitter so that one of the
widgets (assume that there are 2 widgets in the spllitter) in the spllitter will be less
than 32 pixels in width.

The code:

class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):

        self.resize(400,400)

        m = QtGui.QSplitter(self)
        m.resize(200, 100)

        x = QtGui.QPushButton(m)
        x.setGeometry(0, 0, 100, 100)

        y = QtGui.QPushButton(m)
        y.setGeometry(0, 100, 100, 100)


        m.setSizes([20, 180])
        # this will show you that the width of x is 32 (it should be 20!)
        print x.width()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

咆哮 2024-12-07 23:23:37

注意:我使用的是 Python 3.6.2 和 PyQt5,尽管示例中的逻辑保持不变,即使您使用其他版本的 Python 和 PyQt 也可以理解。

看看是什么这里说:

如果指定大小为 0,则小部件将不可见。 保留小部件的大小策略。也就是说,小于相应小部件的最小尺寸提示的值将被提示的值替换。

解决您的问题的选项之一是调用 x.setMinimumWidth() 具有较小的值,例如:

x.setMinimumWidth(1)

但是,如果您自己尝试一下,您会发现

  1. 这是一个肮脏的黑客,因为它实际上将小部件留在这里,只是使其变得非常窄,
  2. 尽管现在您可以拖动拆分器,小部件的初始宽度仍然是“32” “20”。

x.setMinimumWidth(0)

也无法按预期工作:其最小宽度默认情况下实际上为零(因为此小部件没有内容,我猜),但它不能帮助您使拆分项目的宽度小于 32 像素,除非您折叠它。

顺便说一句,

m.setCollapsible(0, False)
m.setCollapsible(1, False)

如果您希望拆分器停止折叠其两个子窗口小部件,请设置。更多详细信息此处。

我找到的解决方案是重载 <要包含到拆分器中的小部件的 code>sizeHint() 方法,如下例所示(查看 ButtonWrapper 类以及现在的输出)。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#Python 3.6.2 and PyQt5 are used in this example


from PyQt5.QtWidgets import (
  QPushButton,
  QSplitter,
  QWidget,
  QApplication,
)

import sys


class ButtonWrapper(QPushButton):

    def sizeHint(self):

        return self.minimumSize()


class Example(QWidget):

    def __init__(self):

        super().__init__()
        self.initUI()

    def initUI(self):

        self.resize(400, 400)

        m = QSplitter(self)
        m.resize(200, 100)

        x = ButtonWrapper(self)
        x.setGeometry(0, 0, 100, 100)

        y = QPushButton(self)
        y.setGeometry(0, 100, 100, 100)

        m.addWidget(x)
        m.addWidget(y)

        m.setSizes([20, 180])

        #Now it really shows "20" as expected
        print(x.width())

        #minimumWidth() is zero by default for empty QPushButton
        print(x.minimumWidth())

        #Result of our overloaded sizeHint() method
        print(x.sizeHint().width())
        print(x.minimumSizeHint().width())

        self.setWindowTitle('Example')
        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

我不确定这是否是正确的做事方式,但我花了很多时间试图解决与此相关的我自己的问题,但到目前为止还没有看到任何令人满意的事情。如果有人知道更好的实际工作和使用方法,我将非常感激。明确的解决方法。

Note: I'm using Python 3.6.2 and PyQt5, though the logic in the example stays the same and can be understood even if you're using other versions of Python and PyQt.

Look at what is said here:

If you specify a size of 0, the widget will be invisible. The size policies of the widgets are preserved. That is, a value smaller than the minimal size hint of the respective widget will be replaced by the value of the hint.

One of the options to solve your problem is to call x.setMinimumWidth() with a small value, like:

x.setMinimumWidth(1)

However, if you'll try it yourself, you'll see that

  1. it is a dirty hack as it actually leaves the widget here, just makes it very narrow and
  2. though now you can drag the splitter, the initial width of the widget is still "32" instead of "20".

x.setMinimumWidth(0)

also doesn't work as expected: its minimal width is actually zero by default (as this widget has no contents, I guess), but it doesn't help you to make splitter item less than 32 pixels wide unless you collapse it.

By the way, set

m.setCollapsible(0, False)
m.setCollapsible(1, False)

if you want splitter to stop collapsing its two children widgets. More details here.

The solution I've found is to overload sizeHint() method of the widget you want to include into the splitter, as in example below (look at the ButtonWrapper class and what is output like now).

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#Python 3.6.2 and PyQt5 are used in this example


from PyQt5.QtWidgets import (
  QPushButton,
  QSplitter,
  QWidget,
  QApplication,
)

import sys


class ButtonWrapper(QPushButton):

    def sizeHint(self):

        return self.minimumSize()


class Example(QWidget):

    def __init__(self):

        super().__init__()
        self.initUI()

    def initUI(self):

        self.resize(400, 400)

        m = QSplitter(self)
        m.resize(200, 100)

        x = ButtonWrapper(self)
        x.setGeometry(0, 0, 100, 100)

        y = QPushButton(self)
        y.setGeometry(0, 100, 100, 100)

        m.addWidget(x)
        m.addWidget(y)

        m.setSizes([20, 180])

        #Now it really shows "20" as expected
        print(x.width())

        #minimumWidth() is zero by default for empty QPushButton
        print(x.minimumWidth())

        #Result of our overloaded sizeHint() method
        print(x.sizeHint().width())
        print(x.minimumSizeHint().width())

        self.setWindowTitle('Example')
        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

I'm not sure if this is the right way to do stuff, but I've spent lots of time trying to solve my own problem connected to this, and haven't seen anything satisfying yet so far. I'll really appreciate it if someone knows a better actually working & clear workaround.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文