开发者

PYQT QSplitter issue

开发者 https://www.devze.com 2023-03-30 10:27 出处:网络
I use QSplitter and I found out that the minumum width of a widget in the splitter is32 pixels (and 23 pixels in height). Does anybody body knows how

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 th开发者_如何转开发at 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()


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号