我想解释一下我想要实现的目标,这是行不通的。当用户绘制矩形或圆形时,想要绘制圆形内部的圆环和矩形内部具有圆形边缘的矩形圆环。到目前为止,我的代码已经实现了...如下所示
如上所示,应从外部矩形中减去内部矩形。并且边缘应该是圆的。
我想要实现的目标,并且对于圆形很相似
代码:
from PyQt5 import QtCore, QtGui, QtWidgets
class Foo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setGeometry(QtCore.QRect(200, 100, 800, 800))
self.button = Button()
self.paint = Createpaintwidget()
self.button.valuesChanged.connect(self.paint.set_size_squares)
self.button.valueChanged.connect(self.paint.set_size_round)
self.lay = QtWidgets.QVBoxLayout(self)
self.lay.addWidget(self.paint)
self.lay.addWidget(self.button)
class Createpaintwidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.sizeHint()
self.setBackgroundRole(QtGui.QPalette.Base)
self.setAutoFillBackground(True)
self._size = QtCore.QSizeF()
self._path = QtGui.QPainterPath()
self._rect = QtCore.QRectF()
self._type = QtGui.QRegion.Rectangle
self._factor = 1.0
self._sizeouter = QtCore.QSizeF()
self._rectouter = QtCore.QRectF()
self._sizeinner = QtCore.QSizeF()
self._rectinner = QtCore.QRectF()
self._pos = QtCore.QPointF()
self._initial_flag = False
fnt = self.font()
fnt.setPointSize(20)
self.setFont(fnt)
print(self._size, self._rect, self._type, self._pos)
def showEvent(self, event):
if not self._initial_flag:
self._pos = self.rect().center()
self._initial_flag = True
@QtCore.pyqtSlot(int, int)
def set_size_squares(self, w, h):
cb, ct, yb = 25, 25, 8
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(w, h)
self._sizeouter = QtCore.QSizeF(w-cb, h-ct)
self._sizeinner = QtCore.QSizeF(w-cb-yb, h-ct-yb)
self._type = QtGui.QRegion.Rectangle
self.updatePath()
print(self._size, self._rect, self._type, self._pos)
@QtCore.pyqtSlot(int)
def set_size_round(self, v):
cb, yb = 25, 8
self._path = QtGui.QPainterPath()
self._size = QtCore.QSizeF(v, v)
self._sizeouter = QtCore.QSizeF(v-cb, v-cb)
self._sizeinner = QtCore.QSizeF(v-cb-yb, v-cb-yb)
self._type = QtGui.QRegion.Ellipse
self.updatePath()
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
if self._type == QtGui.QRegion.Rectangle:
painter.fillRect(self._rectouter, QtGui.QBrush(QtCore.Qt.cyan, QtCore.Qt.SolidPattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rectouter)
painter.fillRect(self._rect, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rect)
painter.fillRect(self._rectinner, QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.setBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
painter.drawRect(self._rectinner)
elif self._type == QtGui.QRegion.Ellipse:
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rect)
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.SolidPattern))
painter.drawEllipse(self._rectouter)
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
painter.drawEllipse(self._rectinner)
def mousePressEvent(self, event):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
self._initial_pos = event.pos()
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
delta = event.pos() - self._initial_pos
self._path.translate(delta)
self._rect.translate(delta)
self._rectinner.translate(delta)
self._rectouter.translate(delta)
self.update()
self._initial_pos = event.pos()
super().mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
QtWidgets.QApplication.restoreOverrideCursor()
super().mouseReleaseEvent(event)
def updatePath(self):
fm = QtGui.QFontMetrics(self.font())
r = QtCore.QRectF(QtCore.QPointF(), self._size)
ro = QtCore.QRectF(QtCore.QPointF(), self._sizeouter)
ri = QtCore.QRectF(QtCore.QPointF(), self._sizeinner)
r.moveCenter(QtCore.QPointF())
ro.moveCenter(QtCore.QPointF())
ri.moveCenter(QtCore.QPointF())
r.moveCenter(QtCore.QPointF())
self._rectouter = QtCore.QRectF(ro)
self._rectinner = QtCore.QRectF(ri)
self._rect = QtCore.QRectF(r)
self._path.moveTo(QtCore.QPointF())
self.update()
def wheelEvent(self, event):
self._factor *= 1.01**(event.angleDelta().y()/15.0)
self.update()
super().wheelEvent(event)
class Button(QtWidgets.QWidget):
valueChanged = QtCore.pyqtSignal(int)
valuesChanged = QtCore.pyqtSignal(int,int)
def __init__(self, parent=None):
super(Button, self).__init__(parent)
roundbutton = QtWidgets.QPushButton('Round')
squarebutton = QtWidgets.QPushButton('Square')
Alay = QtWidgets.QVBoxLayout(self)
Alay.addWidget(roundbutton)
Alay.addWidget(squarebutton)
self.value = QtWidgets.QLabel()
roundbutton.clicked.connect(self.getbuttonfunc)
squarebutton.clicked.connect(self.sqaurebuttonfunc)
@QtCore.pyqtSlot()
def getbuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valueChanged.emit(number)
@QtCore.pyqtSlot()
def sqaurebuttonfunc(self):
number, ok = QtWidgets.QInputDialog.getInt(self, self.tr("Set Number"),
self.tr("Input:"), 1, 1)
if ok:
self.valuesChanged.emit(number, number)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Foo()
w.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
在这些情况下,最好使用QPainterPathStroker
并将其传递给QPainterPath
,因为我有一个带有addRoundedRect()
的圆角矩形:
def paintEvent(self, event):
pen = QtGui.QPen()
brush = QtGui.QBrush(QtCore.Qt.black)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(pen)
painter.setBrush(brush)
painter.translate(self.rect().center())
painter.scale(self._factor, self._factor)
painter.translate(-self.rect().center())
painter.translate(self._pos)
painter.drawPath(self._path)
S = (self._rectouter.size() + self._rectinner.size())/2
s = (self._rectouter.size() - self._rectinner.size())/2
r = QtCore.QRectF(QtCore.QPointF(), S)
r.moveCenter(self._rectouter.center())
path = QtGui.QPainterPath()
painter.setBrush(QtGui.QBrush(QtCore.Qt.gray, QtCore.Qt.Dense7Pattern))
if self._type == QtGui.QRegion.Rectangle:
painter.drawRect(self._rect)
path.addRoundedRect(r, 20, 20)
elif self._type == QtGui.QRegion.Ellipse:
painter.drawEllipse(self._rect)
path.addEllipse(r)
stroker = QtGui.QPainterPathStroker()
stroker.setWidth(s.width())
stroke_path = stroker.createStroke(path)
# painter.setPen(QtCore.Qt.NoPen)
painter.setBrush(QtGui.QBrush(QtCore.Qt.cyan, QtCore.Qt.SolidPattern))
painter.drawPath(stroke_path)