Qt4:在保持中央窗口小部件的大小的同时隐藏次要窗口小部件

时间:2012-10-05 19:07:48

标签: layout qt4 pyqt4 qmainwindow

我有一个带有主“显示”小部件的QMainWindow,还有几个小小部件。我希望能够在鼠标进入或离开窗口时打开/关闭次要小部件。

我可以通过调用显示/隐藏不必要小部件的enterEventleaveEvent来实现此基本功能。但是,Qt4的默认行为是保持QMainWindow几何体固定,并调整重要窗口小部件的大小。我宁愿维护这个小部件的几何形状,并根据需要移动/调整QMainWindow的大小。这可能吗?

这是PyQt4中的简化示例

from PyQt4.QtGui import *
from PyQt4.QtCore import *

app = QApplication([''])

class MyWidget(QWidget):
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)

        layout = QVBoxLayout()
        self.setLayout(layout)
        self.main = QPushButton("major")
        self.main.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.minor = QPushButton("minor")
        layout.addWidget(self.main)
        layout.addWidget(self.minor)

    def enterEvent(self, event):
        self.minor.show()

    def leaveEvent(self, event):
        self.minor.hide()

mw = QMainWindow()
mw.setCentralWidget(MyWidget())
mw.show()

app.exec_()

我希望MyWidget的界限能够改变以包围这个按钮,而不是“主要”按钮增长/缩小。

2 个答案:

答案 0 :(得分:1)

我在Mac OS X上用PySide攻击了你的例子。 经过一段时间的尝试,我找到了以下解决方案:

from PySide.QtGui import *
from PySide.QtCore import *

app = QApplication([''])

class MyWidget(QWidget):
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)

        layout = QVBoxLayout()
        self.setLayout(layout)
        self.main = QPushButton("major")
        self.main.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.minor = QPushButton("minor")
        layout.addWidget(self.main)
        layout.addWidget(self.minor)

    def resizeEvent(self, event):
        self.appendix = self.minor.frameGeometry().height() + 2
        if self.minor.isVisible():
            self.varheight = mw.height() - self.appendix
        else:
            self.varheight = mw.height()

    def enterEvent(self, event):
        self.minor.show()
        mw.resize(mw.width(), self.varheight + self.appendix)

    def leaveEvent(self, event):
        self.minor.hide()
        mw.resize(mw.width(), self.varheight)

mw = QMainWindow()
mw.setCentralWidget(MyWidget())
mw.show()

app.exec_()

这并不完美,因为初始状态不会检查鼠标位置。 魔术“+ 2”也应该可以通过其他一些指标来计算 小部件几何。但是对于这个例子它应该没问题。

这项实施需要几个小时才能完成。确保这一点至关重要 所有计算都处于固定状态。否则布局引擎将产生 很难理解结果甚至是无休止的循环。

resizeEvent从小部件大小中获取正确的值,但没有别的。 enterEventleaveEvent然后使用这些值并进行调整大小。

我的变量未初始化。你可以这样做,但第一次调整大小比我们的其他事件更早。

答案 1 :(得分:0)

你可以试试这段代码。您可以直接将QMainWindow子类化。而不是子类化QWidget。

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MyWindow( QMainWindow ):
    def __init__( self, parent = None ):
        QMainWindow.__init__( self, parent )

        self.widget = QWidget( self )
        lyt = QVBoxLayout()

        self.main = QPushButton( "major" )
        self.minor = QPushButton( "minor" )

        if not self.underMouse() :
            self.minor.hide()
            self.setMaximumHeight( self.main.sizeHint().height() )

        else :
            self.setMaximumHeight( self.minor.sizeHint().height() + self.main.sizeHint().height() )

        lyt.addWidget( self.main )
        lyt.addWidget( self.minor )

        self.widget.setLayout( lyt )
        self.setCentralWidget( self.widget )

    def enterEvent( self, event ) :

        self.minor.show()
        self.setMaximumHeight( self.minor.sizeHint().height() + self.main.sizeHint().height() )
        self.adjustSize()

        event.accept()

    def leaveEvent( self, event ):

        self.minor.hide()
        self.setMaximumHeight( self.main.sizeHint().height() )
        self.adjustSize()

        event.accept()

if __name__ == '__main__' :

    app = QApplication( [] )

    Gui = MyWindow()
    Gui.show()

    app.exec_()