自定义QSizeGrip以调整QListWidget的大小

时间:2018-09-24 20:23:23

标签: python pyqt pyqt4 qlistwidget

我想制作一个QListWidget,在其底部具有一个调整大小的句柄(类似于您在像这样的网页上看到的文本字段)。我见过一些人在问同样的问题,但没有找到完整的例子。

我附近有一些代码,但是在调整大小时它会闪烁,所以我猜想我在调整策略或布局时缺少某些东西……

这是我的“工作中”示例。理论很简单,您只需在小部件的mousePressEvent中测量鼠标移动的距离并相应地调整大小/重新定位即可。不幸的是,我缺少一些基本的东西,我也不知道:

from PyQt4 import QtGui
import sys

class Grip(QtGui.QLabel):
    def __init__(self, parent, move_widget):
        super(Grip, self).__init__(parent)
        self.move_widget = move_widget
        self.setText("+")
        self.min_height = 50

        self.mouse_start = None
        self.height_start = self.move_widget.height()
        self.resizing = False
        self.setMouseTracking(True)


    def showEvent(self, event):
        super(Grip, self).showEvent(event)
        self.reposition()

    def mousePressEvent(self, event):
        super(Grip, self).mousePressEvent(event)
        self.resizing = True
        self.height_start = self.move_widget.height()
        self.mouse_start = event.pos()

    def mouseMoveEvent(self, event):
        super(Grip, self).mouseMoveEvent(event)
        if self.resizing:
            delta = event.pos() - self.mouse_start
            height = self.height_start + delta.y()
            if height > self.min_height:
                self.move_widget.setFixedHeight(height)
            else:
                self.move_widget.setFixedHeight(self.min_height)

            self.reposition()

    def mouseReleaseEvent(self, event):
        super(Grip, self).mouseReleaseEvent(event)
        self.resizing = False

    def reposition(self):
        rect = self.move_widget.geometry()
        self.move(rect.right(), rect.bottom())


class Dialog(QtGui.QDialog):
    def __init__(self):
        super(Dialog, self).__init__()
        layout = QtGui.QVBoxLayout()
        self.setLayout(layout)
        list_widget = QtGui.QListWidget()
        layout.addWidget(list_widget)
        gripper = Grip(self, list_widget)

        layout.addWidget(QtGui.QLabel("Test"))

        self.setGeometry(200, 500, 200, 500)

4 个答案:

答案 0 :(得分:2)

尝试一下:

while not blah blah:
    function()

答案 1 :(得分:2)

我认为,您应该使用QSizeGrip来实现自己的QSplitter

from PyQt4 import QtCore, QtGui
import sys


class Dialog(QtGui.QDialog):
    def __init__(self):
        super(Dialog, self).__init__()
        layout = QtGui.QVBoxLayout(self)

        splitter = QtGui.QSplitter(QtCore.Qt.Vertical)
        layout.addWidget(splitter)
        list_widget = QtGui.QListWidget()
        splitter.addWidget(list_widget)
        splitter.addWidget(QtGui.QLabel("Test"))


if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = Dialog()
    w.show()
    sys.exit(app.exec_())

答案 2 :(得分:2)

作为其他解决方案的替代方案,您可以使用QSizeGrip开箱即用的方式:

from PyQt4 import QtCore, QtGui
import sys

class Dialog(QtGui.QDialog):
    def __init__(self):
        super(Dialog, self).__init__()
        layoutMain = QtGui.QVBoxLayout(self)
        listWidget = QtGui.QListWidget(self)
        gripper = QtGui.QSizeGrip(listWidget)
        l = QtGui.QHBoxLayout(listWidget)

        l.setContentsMargins(0, 0, 0, 0)
        l.addWidget(gripper, 0, QtCore.Qt.AlignRight | QtCore.Qt.AlignBottom)

        layoutMain.addWidget(listWidget)
        layoutMain.addWidget(QtGui.QLabel("Test", self))

        self.setGeometry(200, 500, 200, 500)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = Dialog()
    w.show()
    sys.exit(app.exec_())

答案 3 :(得分:1)

好吧,我真该死。我在这里将答案发布给希望解决类似问题的其他人!

与原始代码相比,我真正需要更改的只是引用globalPos()而不是本地pos()。感谢您的帮助,特别是S. Nick指出移动事件是造成此问题的原因。

from PyQt4 import QtGui
import sys

class Grip(QtGui.QLabel):
    def __init__(self, parent, move_widget):
        super(Grip, self).__init__(parent)
        self.move_widget = move_widget
        self.setText("+")
        self.min_height = 50

        self.mouse_start = None
        self.height_start = self.move_widget.height()
        self.resizing = False
        self.setMouseTracking(True)

        self.setCursor(QtCore.Q.SizeVerCursor)


    def showEvent(self, event):
        super(Grip, self).showEvent(event)
        self.reposition()

    def mousePressEvent(self, event):
        super(Grip, self).mousePressEvent(event)
        self.resizing = True
        self.height_start = self.move_widget.height()
        self.mouse_start = event.globalPos()

    def mouseMoveEvent(self, event):
        super(Grip, self).mouseMoveEvent(event)
        if self.resizing:
            delta = event.globalPos() - self.mouse_start
            height = self.height_start + delta.y()
            if height > self.min_height:
                self.move_widget.setFixedHeight(height)
            else:
                self.move_widget.setFixedHeight(self.min_height)

            self.reposition()

    def mouseReleaseEvent(self, event):
        super(Grip, self).mouseReleaseEvent(event)
        self.resizing = False

    def reposition(self):
        rect = self.move_widget.geometry()
        self.move(rect.right(), rect.bottom())


class Dialog(QtGui.QDialog):
    def __init__(self):
        super(Dialog, self).__init__()
        layout = QtGui.QVBoxLayout()
        self.setLayout(layout)
        list_widget = QtGui.QListWidget()
        layout.addWidget(list_widget)
        gripper = Grip(self, list_widget)

        layout.addWidget(QtGui.QLabel("Test"))

        self.setGeometry(200, 500, 200, 500)