Пользовательский QSizeGrip для изменения размера QListWidget - PullRequest
0 голосов
/ 24 сентября 2018

Я хочу сделать 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 голосов
/ 25 сентября 2018

Хорошо, оказывается, я был чертовски близко.Я выкладываю здесь ответ для всех, кто хочет решить подобную проблему!

Все, что мне действительно нужно было изменить, - это сослаться на 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)
0 голосов
/ 25 сентября 2018

Я думаю, что вместо реализации вашего собственного 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_())
0 голосов
/ 25 сентября 2018

В качестве альтернативы другим решениям вы можете использовать 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_())
0 голосов
/ 25 сентября 2018

Попробуйте:

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()                                             # <- +++
...