QBrush - 缩放标准填充点画图案? [英] QBrush - scale a standard fill stipple pattern?

查看:44
本文介绍了QBrush - 缩放标准填充点画图案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 PyQt 中,我有一个 QGraphicsScene,我向其中添加了一个带有标准 QBrush 填充模式之一的矩形,在本例中为 Qt.Dense7Pattern.当场景以原始 1:1 比例显示时,这会按预期显示:组成 Dense7Pattern 的点"彼此相隔一定数量的像素,假设相隔 5 个像素只是为了选择一个数字.另外,假设原始矩形宽 50 像素,高 50 像素.

In PyQt, I have a QGraphicsScene to which I add a rectangle with one of the standard QBrush fill patterns, in this case Qt.Dense7Pattern. This shows up as expected when the scene is displayed at original 1:1 scale: the "dots" that make up the Dense7Pattern are some number of pixels apart from each other, let's say 5 pixels apart just to pick a number. Also, let's say the original rectangle is 50 pixels wide and 50 pixels tall.

当我放大那个场景时,假设放大 2 倍,使填充矩形现在显示为 100x100 像素,我希望填充图案的点仍然相距 5 个像素,但是,Qt 放大静态填充图案也是如此,使填充图案的点相距 10 个像素.

When I zoom in on that scene, let's say by a factor of 2, making the filled rectangle now appear 100x100 pixels, I would like the dots of the fill pattern to still appear 5 pixels apart, but, Qt zooms in on the static fill pattern too, making the dots of the fill pattern appear 10 pixels apart.

这个问题看起来很相似.显然,您可以将变换(包括缩放)应用于画笔的像素图填充图案,但是,它似乎不适用于画笔的标准"填充图案.我做了子类并在paint方法中更改了画笔的变换,但没有运气:

This question looks similar. Apparently you can apply a transform (including scale) to a brush's pixmap fill pattern, but, it doesn't seem to apply to the brush's 'standard' fill pattern. I did the subclass and changed the brush's transform in the paint method, but no luck:

整个子类(希望我做了所有必要的事情):

The entire subclass (hopefully I did everything that's necessary):

class customFillPolygonItem(QGraphicsPolygonItem):
    def paint(self,painter,option,widget=None):
        # from here, painter.setBrush affects shapes drawn directly in this function;
        #  self.setBrush affects the call to super().paint
        newBrush=QBrush(painter.brush())
        newBrush.setTransform(QTransform(painter.worldTransform().inverted()[0]))
        self.setBrush(newBrush)
        painter.setBrush(newBrush)
        painter.drawRect(QRectF(0,0,50,50)) # draw a reality-check object
        super(customFillPolygonItem,self).paint(painter,option,widget)

然后我只是使用

myItem=customFillPolygonItem(QPolygonF(...
myItem.setBrush(QBrush(Qt.Dense7Pattern))
myScene.addItem(myItem)

那么 - 是否可以将比例应用于画笔的标准填充图案?这将类似于 QBrush.setFlag(ItemIgnoresTransformations) 但这样的东西不存在......你只能在整个项目(在这种情况下为矩形)上设置该标志.

So - is it possible to apply the scale to the a brush's standard fill pattern? This would be similar to QBrush.setFlag(ItemIgnoresTransformations) but such a thing does not exist... you can only set that flag on the entire item (rectangle in this case).

解决方法可能包括:- 使用 ItemIgnoresTransformations 并根据需要手动转换实际的矩形顶点- 从每个标准填充图案中制作一个 qpixmap,然后使用该像素图作为画笔,在这种情况下,它应该按照上述问题进行缩放

Workarounds might include: - use ItemIgnoresTransformations and manually transform the actual rectangle vertices as needed - make a qpixmap out of each standard fill pattern, then use that pixmap as the brush in which case it should scale as in the question mentioned above

当然,找到最简单的解决方案会很好.

But of course it would be nice to find the simplest solution.

更新: Schollii 回答了提出的问题;他关于查看 alpha 值的建议也导致了我在这种特殊情况下遇到的更大问题的解决方案 - 创建不同的灰度,在我发布的解决方案中详细说明,这实际上并不是我提出的问题的解决方案.无论如何,谢谢!

UPDATE: Schollii answers the question that was asked; his suggestion to look in to alpha values also led to the solution to the larger issue I was having in this particular case - to create different grayscales, spelled out in the solution I posted, which is not actually a solution to the question I asked. Anyway, thanks!

推荐答案

我相信通过变换无法达到目标:在场景"空间中生成填充图案,然后根据视图比例因子对其应用变换,显然这会增加点之间的间距,没有任何变换可以阻止这一点,只能绘制不同的图案.

I believe the goal is not reachable via a transform: the fill pattern is generated in "scene" space then a transform is applied to it based on view scale factor, clearly this is going to increase the spacing between points, no transformation can prevent that, only a different drawing of the pattern.

要获得您想要的效果,画笔必须有一个参数来控制场景坐标中点之间的距离;然后在 rect 的paint() 方法中,您可以根据当前视图缩放因子设置此参数值(通过paint() 方法的style 参数).

To get effect you're after, the brush would have to have a parameter to control the distance between points in scene coords; then in the paint() method of the rect you could set this parameter value based on current view zoom factor (via the style argument to paint() method).

因为我认为 QBrush 没有提供这样的参数,所以你必须自己绘制点,使用前一段中描述的计算距离.从 Python 完成,如果有丢失的点,这可能会很慢,但是 PyQt5 总体上具有相当令人印象深刻的性能.

Since I don't think the QBrush provides such parameter, you have to draw the dots yourself, using distance computed as described in previous paragraph. Done from Python, this might be quite slow if there are Los of dots, but then again PyQt5 has quite impressive performance in general.

并不是说您必须为点选择原点(角落或中心将是典型的选择),并且当您放大时,您会看到点向原点滑动",因为添加了更多点"到相反的两端/边缘.我认为您很可能不会喜欢这种效果,而且由于它不太容易实现,您可能需要考虑一种不基于点的不同视觉效果,例如渐变或 alpha 值.可能还有其他方法,例如 setDashPattern() 或在视图坐标中绘制休息,但可能不值得付出努力.

Not that you will have to pick an origin for the points (a corner or the center would be typical choices), and as you zoom in you will see the points "slide" towards the origin, as more points are "added" to the opposite ends/edges. I think there is a good chance you won't like the effect and since it is not so easy to implement, you might want to consider a different visual effect that would not be based on points, like a gradient or an alpha value. There might be other approaches, like setDashPattern() or drawing a rest in view coordinates but probably not worth the effort.

这篇关于QBrush - 缩放标准填充点画图案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆