在 python 中的文本后面制作一个矩形框

Making a rectangle box behind text in python

我正在开发文本编辑器。留给我的唯一问题是在文本后面绘制一个矩形框(颜色为不透明度 50%),该文本应该能够在文本工作时随文本拖放到任何地方。此外,文本应始终适合该矩形框。提前致谢。

import os
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

from PIL import Image, ImageFont, ImageDraw, ImageEnhance


class PhotoViewer(QtWidgets.QGraphicsView):
    photoClicked = QtCore.pyqtSignal(QtCore.QPoint)

    def __init__(self, parent):
        super(PhotoViewer, self).__init__(parent)
        self._zoom = 0
        self._empty = True
        self._scene = QtWidgets.QGraphicsScene(self)
        self._photo = QtWidgets.QGraphicsPixmapItem()

        self._textLayer = QtWidgets.QGraphicsSimpleTextItem ()


        #self._textLayer.setFont(QFont ())

        self._scene.addItem(self._photo)
        self._scene.addItem(self._textLayer)

        self.setScene(self._scene)
        self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(80, 30, 30)))
        self.setFrameShape(QtWidgets.QFrame.NoFrame)
        self._textLayer.setFlags(QGraphicsItem.ItemIsMovable)

    def hasPhoto(self):
        return not self._empty

    def fitInView(self, scale=True):
        rect = QtCore.QRectF(self._photo.pixmap().rect())
        if not rect.isNull():
            self.setSceneRect(rect)
            if self.hasPhoto():
                unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
                self.scale(1 / unity.width(), 1 / unity.height())
                viewrect = self.viewport().rect()
                scenerect = self.transform().mapRect(rect)
                factor = min(viewrect.width() / scenerect.width(),
                             viewrect.height() / scenerect.height())
                self.scale(factor, factor)
            self._zoom = 0


    def updateText(self,text,font_size=50):
        # Load the font:
        font_db = QFontDatabase()
        font_id = font_db.addApplicationFont("fonts/Summer's Victory Over Spring - TTF.ttf")
        #families = font_db.applicationFontFamilies(font_id)
        #print (families)
        myFont = QFont("Summers Victory Over Spring")
        myFont.setPixelSize(font_size*1.5)
        self._textLayer.setFont(myFont)
        self._textLayer.setText(text)


        self.begin = QtCore.QPoint()
        self.end = QtCore.QPoint()
        self.show()


    def setPhoto(self, pixmap=None):
        self._zoom = 0

        if not pixmap.isNull():
            self._empty = False
            self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)

            self._photo.setPixmap(pixmap)
        else:
            self._empty = True
            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
            self._photo.setPixmap(QPixmap())
        self.fitInView()

    def wheelEvent(self, event):
        if self.hasPhoto():
            if event.angleDelta().y() > 0:
                factor = 1.25
                self._zoom += 1
            else:
                factor = 0.8
                self._zoom -= 1
            if self._zoom > 0:
                self.scale(factor, factor)
            elif self._zoom == 0:
                self.fitInView()
            else:
                self._zoom = 0

    def toggleDragMode(self):
        if self.dragMode() == QtWidgets.QGraphicsView.ScrollHandDrag:
            self.setDragMode(QtWidgets.QGraphicsView.NoDrag)
        elif not self._photo.pixmap().isNull():
            self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)

    def mousePressEvent(self, event):
        if self._photo.isUnderMouse():
            self.photoClicked.emit(QtCore.QPoint(event.pos()))
        super(PhotoViewer, self).mousePressEvent(event)
    def keyReleaseEvent(self, event):
        print ('Key event: %d' % event.key())
        if event.key() == Qt.Key_A:
            #print (dir(self._scene))
            #print (dir(self._photo))
            #print (dir(self._textLayer))
            print ("scene Rect:",self._scene.sceneRect())
            print ("scene WH:",self._scene.width(),self._scene.height())
            print ("gfxPhoto pos:" ,self._photo.pos().x(),self._photo.pos().y())
            print ("gfxPhoto scenepos:" ,self._photo.scenePos())
            #print ("gfxPhoto Rect:",self._photo.boundingRect())
            print ("gfxPhoto XY:",self._photo.x(),self._photo.y())
            print ("gfxtext Rect:",self._textLayer.boundingRect())
            print ("gfxtext scenepos:" ,self._textLayer.scenePos().x(),self._textLayer.scenePos().y())
            print ("gfxtext pos:",self._textLayer.pos().x(),self._textLayer.pos().y())



class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.viewer = PhotoViewer(self)
        # 'Load image' button
        self.btnLoad = QtWidgets.QToolButton(self)
        self.btnLoad.setText('Load image')
        self.btnLoad.clicked.connect(self.loadImage)
        # Button to change from drag/pan to getting pixel info
        self.btnPixInfo = QtWidgets.QToolButton(self)
        self.btnPixInfo.setText('Create Text')
        self.btnPixInfo.clicked.connect(self.loadText)

        self.fontSize =QtWidgets.QSpinBox()
        self.fontSize.valueChanged.connect(self.loadText)

        self.editPixInfo = QtWidgets.QLineEdit(self)
        #self.editPixInfo.setReadOnly(True)
        self.viewer.photoClicked.connect(self.photoClicked)
        # Arrange layout
        VBlayout = QtWidgets.QVBoxLayout(self)
        HBlayout = QtWidgets.QHBoxLayout()
        HBlayout.setAlignment(QtCore.Qt.AlignLeft)
        HBlayout.addWidget(self.btnLoad)
        HBlayout.addWidget(self.btnPixInfo)
        HBlayout.addWidget(self.editPixInfo)
        VBlayout.addLayout(HBlayout)
        VBlayout.addWidget(self.viewer)
        HBlayout.addWidget(self.fontSize)
        self.editPixInfo.setText("Sheeda")
        self.fontSize.setValue(20)
        self.loadImage()
        self.loadText()
        self.frame = QFrame()
        self.frame.setFrameStyle(QFrame.StyledPanel)
        self.frame.setLineWidth(20)

    def loadImage(self):
        print(os.path.exists(os.path.abspath('E:\Dpinner\images\pic2.png')))
        self.viewer.setPhoto(QtGui.QPixmap(os.path.abspath('E:\Dpinner\images\pic2.png')))

    def loadText(self):
        #self.viewer.toggleDragMode()
        self.viewer.updateText(self.editPixInfo.text(),self.fontSize.value())
    def photoClicked(self, pos):
        if self.viewer.dragMode()  == QtWidgets.QGraphicsView.NoDrag:
            self.editPixInfo.setText('%d, %d' % (pos.x(), pos.y()))


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 800, 600)
    window.show()
    sys.exit(app.exec_())

代码结束。提前致谢

如果您想在文本上添加一个矩形,您可以创建自定义 QGraphicsSimpleTextItem,如下所示:

class GraphicsSimpleTextItem(QtWidgets.QGraphicsSimpleTextItem):
    def paint(self, painter, option, widget):
        super(GraphicsSimpleTextItem, self).paint(painter, option, widget)
        painter.save()
        color = QtGui.QColor(QtCore.Qt.red)
        color.setAlpha(127)
        painter.fillRect(self.boundingRect(), QtGui.QBrush(color))
        painter.restore()

然后你把它放在你的代码中:

self._textLayer = GraphicsSimpleTextItem()