代码之家  ›  专栏  ›  技术社区  ›  Spencer

自定义QSizeGrip以调整QListWidget的大小

  •  3
  • Spencer  · 技术社区  · 6 年前

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

    我有一些代码,这是几乎在那里,但它闪烁在调整大小,所以我猜有一些东西,我错过了调整大小的政策或布局或东西。。。

    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 回复  |  直到 6 年前
        1
  •  3
  •   S. Nick    6 年前

    试试看:

    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
    
        self.reposition()                                             # <- +++
    
        2
  •  3
  •   Spencer    6 年前

    除其他解决方案外,您还可以使用 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
  •  2
  •   eyllanesc Yonghwan Shin    6 年前

    我认为与其自己实施 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_())
    
        4
  •  2
  •   Spencer    6 年前

    好吧,原来我真的很接近。我在这里为任何想解决类似问题的人发布了一个答案!

    我真正需要改变的是引用 globalPos() 而不是当地的 pos()

    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)