Python Qt绑定:setCosmetic()和sceneRect(),边距问题

时间:2014-10-07 08:08:07

标签: python qt pyqt drawing pyside

使用以下简单示例(适用于PySide或PyQt4):

import sys
import random
import numpy
from PySide import QtGui, QtCore

class Window(QtGui.QWidget):

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

        self.resize(600, 400)
        self.view = QtGui.QGraphicsView()
        self.scene = QtGui.QGraphicsScene()
        self.view.setScene(self.scene)
        self.setWindowTitle('Example')

        # Layout
        layout = QtGui.QGridLayout()
        layout.addWidget(self.view, 0, 0)
        self.setLayout(layout)

        # Styles
        self.pen = QtGui.QPen(QtCore.Qt.black, 0, QtCore.Qt.SolidLine)
        self.brush = QtGui.QBrush(QtGui.QColor(255, 255, 255, 0))

    def addLine(self, x0, y0, x1, y1):
        line = QtCore.QLineF(x0, -y0, x1, -y1)
        pen = QtGui.QPen(QtGui.QColor(0, 0, 255, 255), 0, QtCore.Qt.SolidLine)
        l = self.scene.addLine(line, pen)

    def addRect(self, left, top, width, height):
        rect = QtCore.QRectF(left, -top, width, abs(height))
        r = self.scene.addRect(rect, self.pen, self.brush)

    def fit(self):
        self.view.fitInView(self.scene.sceneRect())

    def resizeEvent(self, event = None):
        self.fit()


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    window.addLine(-1, -1, 2, 2)
    window.addLine(0, 1, 1, 0)
    window.addRect(0, 1, 1, 1)
    window.fit()
    sys.exit(app.exec_())

我可以绘制一个矩形和两条穿过它的蓝线。请注意,使用宽度为QtGui.QPen的{​​{1}}会使蓝线的宽度不变,无论是方形/线条的大小,还是窗口的大小:

enter image description here enter image description here

这是因为零宽度笔默认是装饰性的。根据Qt文档:

  

化妆笔用于绘制宽度恒定的笔画   不管应用于0的任何变换   用于。用化妆笔绘制形状可确保其轮廓   在不同比例因子下具有相同的厚度。

使用方法QPainter,非零宽度笔也可以设置为装饰。因此,将示例的setCosmetic(True)方法中的笔宽设置为addLine(),并将笔设置为装饰:

2

提供以下输出:

enter image description here enter image description here

正如你所看到的,边距是巨大的,我真的希望交叉线在窗口的左下角和右上角开始和结束,没有边距。

似乎添加了这些边距是因为 def addLine(self, x0, y0, x1, y1): line = QtCore.QLineF(x0, -y0, x1, -y1) pen = QtGui.QPen(QtGui.QColor(0, 0, 255, 255), 2, QtCore.Qt.SolidLine) pen.setCosmetic(True) l = self.scene.addLine(line, pen) 被修改,好像这条线不是装饰性的。例如,请参见此案例,其中宽度也设置为scene.sceneRect(),但笔未设置为装饰:

2

enter image description here

为什么会这样?不应仅在 def addLine(self, x0, y0, x1, y1): line = QtCore.QLineF(x0, -y0, x1, -y1) pen = QtGui.QPen(QtGui.QColor(0, 0, 255, 255), 2, QtCore.Qt.SolidLine) l = self.scene.addLine(line, pen) 时添加额外的保证金吗?如果这种行为是故意的,有人可以解释原因吗?

另外,有没有办法避免它?东西"清洁",不同于在将线条添加到场景之前手动更改线条的边界(或者不同于稍后从场景中减去额外边距)。也许有一个配置参数或另一种方法将线添加到场景中?

修改

将帽子样式设置为" flat"虽然问题仍然存在,但结果是利润率较低:

isCosmetic() == False

enter image description here

再次,我们可以看到边距与使用非化妆笔的方式相同:

enter image description here

1 个答案:

答案 0 :(得分:0)

这不是答案,但我认为这可能会有所帮助:

我是用C ++做的,但翻译起来很容易。在QGraphicsView中,设置滚动条策略:

view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

然后在调用fitInView时,添加以下标志:

view->fitInView(scene->sceneRect(), Qt::KeepAspectRatioByExpanding);