QPainter 中的重叠半透明 QRectangles
Overlapping semitransparent QRectangles in QPainter
当两个矩形重叠时,我注意到两者之间的交叉点变得更加不透明,据我了解,这是由于添加了 QBrush alphas。
重叠交叉点变得更加不透明的视觉示例:
我想防止重叠的交叉点变得更加不透明,该区域应该与其余矩形的颜色相同。 (当使用完全不透明的 QColors 时会发生这种情况,但我想使用半透明的)。
我已经阅读了关于这个主题的几个主题(包括这个非常相似的问题:), every answer is stating that the problem can be solved by changing the Composition Mode of the painter, however I just can't find a composition mode that provide the expected result, I have tried all of the 34 Composition Modes listed in the Qpainter documentation (https://doc.qt.io/qt-5/qpainter.html#setCompositionMode)。一些模式只是将 QColor 完全不透明,大多数与这个问题无关,none 其中允许我让两个矩形的交点保持与其余部分相同的半透明颜色。
如果有人有想法,我将不胜感激。
您可以在下面找到重现该问题的简短代码:
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtCore import QRect
import sys
class Drawing(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(300, 300, 350, 300)
self.show()
def paintEvent(self, event):
painter = QPainter(self)
painter.setCompositionMode(QPainter.CompositionMode_SourceOver)
painter.setPen(QColor(128, 128, 255, 128))
painter.setBrush(QColor(128, 128, 255, 128))
rect1 = QRect(10,10,100,100)
rect2 = QRect(50,50,100,100)
painter.drawRect(rect1)
painter.drawRect(rect2)
def main():
app = QApplication(sys.argv)
ex = Drawing()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
简单的解决方案是使用 QPainterPath,确保它都使用 setFillRule(Qt.WindingFill)
and use the simplified()
版本的路径,合并所有子路径:
path = QPainterPath()
path.setFillRule(Qt.WindingFill)
path.addRect(10, 10, 100, 100)
path.addRect(50, 50, 100, 100)
painter.drawPath(path.simplified())
当两个矩形重叠时,我注意到两者之间的交叉点变得更加不透明,据我了解,这是由于添加了 QBrush alphas。
重叠交叉点变得更加不透明的视觉示例:
我想防止重叠的交叉点变得更加不透明,该区域应该与其余矩形的颜色相同。 (当使用完全不透明的 QColors 时会发生这种情况,但我想使用半透明的)。
我已经阅读了关于这个主题的几个主题(包括这个非常相似的问题:
如果有人有想法,我将不胜感激。
您可以在下面找到重现该问题的简短代码:
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtCore import QRect
import sys
class Drawing(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(300, 300, 350, 300)
self.show()
def paintEvent(self, event):
painter = QPainter(self)
painter.setCompositionMode(QPainter.CompositionMode_SourceOver)
painter.setPen(QColor(128, 128, 255, 128))
painter.setBrush(QColor(128, 128, 255, 128))
rect1 = QRect(10,10,100,100)
rect2 = QRect(50,50,100,100)
painter.drawRect(rect1)
painter.drawRect(rect2)
def main():
app = QApplication(sys.argv)
ex = Drawing()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
简单的解决方案是使用 QPainterPath,确保它都使用 setFillRule(Qt.WindingFill)
and use the simplified()
版本的路径,合并所有子路径:
path = QPainterPath()
path.setFillRule(Qt.WindingFill)
path.addRect(10, 10, 100, 100)
path.addRect(50, 50, 100, 100)
painter.drawPath(path.simplified())