首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python绑定: setCosmetic()和sceneRect(),边距问题

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

Stack Overflow用户
提问于 2014-10-07 08:08:06
回答 1查看 479关注 0票数 3

通过下面的简单示例( PySide或PyQt4都能很好地工作):

代码语言:javascript
复制
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.QPen0使蓝线具有恒定的宽度--无论是平方/行的大小还是窗口的大小:

这是因为零宽度钢笔在默认情况下是美容的。根据Qt文档:

化妆品笔是用来画笔画,有一个恒定的宽度,无视任何转换应用到他们使用的QPainter。用一支化妆笔画一个形状,可以确保它的轮廓在不同的尺度因素下具有相同的厚度。

非零宽度笔也可以设置为化妆品,使用的方法setCosmetic(True).因此,将示例的addLine()方法中的笔宽设置为2,并将笔设置为化妆品:

代码语言:javascript
复制
    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,但笔不设为化妆品:

代码语言:javascript
复制
    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)

为什么会发生这种情况?难道不应该只在isCosmetic() == False时添加额外的边距吗?如果这种行为是故意的,有人能解释原因吗?

还有,有什么办法可以避免吗?“干净”的东西,与在将行添加到场景之前手动更改边框不同(或者与后面从场景减去额外的边距不同)。也许有一个配置参数,或者是另一种将行添加到场景的方法?

编辑

将上限样式设置为“平面”会使边距变小,尽管问题仍然存在:

代码语言:javascript
复制
    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)
        pen.setCapStyle(QtCore.Qt.FlatCap)
        l = self.scene.addLine(line, pen)

再一次,我们可以看到,如果我们使用一支非化妆笔,毛边是如何相同的:

EN

回答 1

Stack Overflow用户

发布于 2015-06-10 21:39:20

这并不是完全正确的答案,但我认为这可能会有所帮助:

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

代码语言:javascript
复制
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

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

代码语言:javascript
复制
view->fitInView(scene->sceneRect(), Qt::KeepAspectRatioByExpanding);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26231374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档