【问题标题】:Limit child widget move range in parent widget限制父小部件中的子小部件移动范围
【发布时间】:2020-07-08 22:10:38
【问题描述】:

我正在做一个拖放小部件功能。我在网上复制了一段代码,重写了三个类mousePressEvent、mouseReleaseEvent和mouseMoveEvent。

当子部件移动到父部件的边框时,它会覆盖父部件的边框。我不希望它变成这样。我想保留父小部件的边框。有没有办法让子widget只在父widget的内容区移动

我尝试了几种方法,但都失败了

首先:设置父控件布局的setContentsMargins属性

第二:设置父控件的内边距

第三:设置子控件的边距

import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt, QMimeData, QDataStream, QIODevice, QByteArray, QPoint, QSize
from PyQt4.QtGui import QLabel, QWidget, QHBoxLayout, QStyleOption, QPainter, QStyle, QDrag, QListWidgetItem, QIcon, \
    QFontMetricsF, QColor


class Label(QWidget):
    def __init__(self):
        super(Label, self).__init__()

        self.setStyleSheet("""
            *{             border-width: 1px;
             border-style: solid;
             border-color: #cdcdcd;
             background-color:blue
             }
        """)
        self.setFixedSize(300, 300)

    def paintEvent(self, event):
        super(Label, self).paintEvent(event)
        opt = QStyleOption()
        opt.initFrom(self)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)

    def mousePressEvent(self, event):
        self.__mousePressPos = None
        self.__mouseMovePos = None
        if event.button() == QtCore.Qt.LeftButton:
            self.__mousePressPos = event.globalPos()
            self.__mouseMovePos = event.globalPos()

        super(Label, self).mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.buttons() == QtCore.Qt.LeftButton:
            # adjust offset from clicked point to origin of widget
            currPos = self.mapToGlobal(self.pos())
            globalPos = event.globalPos()
            diff = globalPos - self.__mouseMovePos
            newPos = self.mapFromGlobal(currPos + diff)
            self.move(newPos)

            self.__mouseMovePos = globalPos

        super(Label, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        if self.__mousePressPos is not None:
            moved = event.globalPos() - self.__mousePressPos
            if moved.manhattanLength() > 3:
                event.ignore()
                return

        super(Label, self).mouseReleaseEvent(event)


class Widget(QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        box = QHBoxLayout()
        box.setContentsMargins(20, 20, 20, 20)
        self.setLayout(box)
        box.addWidget(Label())
        self.setFixedSize(500, 500)

        self.setStyleSheet("""
            *{             border-width: 10px;
             border-style: solid;
             border-color: red;}
        """)

    def paintEvent(self, event):
        super(Widget, self).paintEvent(event)
        opt = QStyleOption()
        opt.initFrom(self)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)


class Example(QtGui.QWidget):

    def __init__(self):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):
        h = QtGui.QHBoxLayout()
        h.addWidget(Widget())
        self.setLayout(h)
        self.setGeometry(100, 100, 900, 000)
        self.setWindowTitle("PyQt")
        self.show()


def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

【问题讨论】:

  • 你可以放一张你想要得到的图片(或草图)。
  • 没看懂你的意思,能不能具体点,谢谢!
  • @eyllanesc我之前的问题表达的不是很清楚,我已经更新了我的问题描述,麻烦您了

标签: python pyqt pyqt4


【解决方案1】:

父 QWidget 始终绘制在子元素下方,因此您可以看到这种效果。解决方案是在包含红色边框的蓝色子项之上创建另一个子项,该子项占用与父项相同的大小(这是通过布局实现的)并且不会阻止鼠标事件(因为默认情况下小部件将鼠标锁定到较低的小部件,但可以使用 Qt::WA_TransparentForMouseEvents 标志禁用)。

class Widget(QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        self.setFixedSize(500, 500)

        container = QWidget()
        container.setAttribute(Qt.WA_TransparentForMouseEvents)
        container.setStyleSheet(
            """
            *{             border-width: 10px;
             border-style: solid;
             border-color: red;}
        """
        )

        box = QHBoxLayout(self)
        box.setContentsMargins(0, 0, 0, 0)
        box.addWidget(container)

        label = Label()
        label.setParent(self)

        container.raise_()

【讨论】:

  • 非常感谢远方的你,解决了我的大问题
猜你喜欢
  • 1970-01-01
  • 2020-01-01
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
  • 1970-01-01
  • 2013-07-28
  • 2019-06-26
相关资源
最近更新 更多