PYQT QSplitter issue

a 夏天 提交于 2019-12-12 13:33:51

问题


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()

回答1:


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.



来源:https://stackoverflow.com/questions/7167929/pyqt-qsplitter-issue

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!