如何在已放置的 QLabel 或 QPixmap 上使用 QPainter 绘图?
How to draw with QPainter on top of already placed QLabel or QPixmap?
在尝试使用 Python 和 PyQt5 时,我遇到了一个问题。我的 GUI 中有几个标签 (QLabel) 和图像 (QPixmap),我想在它们上面画一些东西,这取决于主程序的功能。我不知道怎么办。例如,我更改了从 class BinColUI 调用 setLabels() 的标签上的文本,然后我想在它们上面画一些东西(即 QPainter.drawLine())。我试过的没有用,没有画出任何东西。我不成功的尝试在 setLabels() 中被注释掉了。
我该怎么做?
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QVBoxLayout, QWidget
class BinColUI(QMainWindow):
def __init__(self):
super().__init__()
self.initUi()
self.createLabelTop()
self.createLabelBot()
def initUi(self):
self.setWindowTitle('Bin Collection')
self.setFixedSize(500, 500)
# self.setStyleSheet('background-color: white')
self.generalLayout = QVBoxLayout()
self._centralWidget = QWidget(self)
self.setCentralWidget(self._centralWidget)
self._centralWidget.setLayout(self.generalLayout)
def paintEvent(self, event):
self.qp = QPainter()
self.qp.begin(self)
self.drawLine(event, self.qp)
self.qp.end()
def drawLine(self, event, qp):
pen = QPen(Qt.red, 3, Qt.SolidLine)
qp.setPen(pen)
qp.drawLine(5, 5, 495, 5)
qp.drawLine(495, 5, 495, 495)
qp.drawLine(495, 495, 5, 495)
qp.drawLine(5, 495, 5, 5)
def createLabelTop(self):
self.label_top = QLabel('PLEASE WAIT')
self.label_top.setAlignment(Qt.AlignCenter)
self.label_top.setFixedSize(450, 60)
self.label_top.setStyleSheet("font: 14pt Bahnschrift; color: black; background-color: yellow")
self.generalLayout.addWidget(self.label_top, alignment=Qt.AlignCenter)
def createLabelBot(self):
self.label_bot = QLabel('PLEASE WAIT')
self.label_bot.setAlignment(Qt.AlignCenter)
self.label_bot.setFixedSize(450, 60)
self.label_bot.setStyleSheet("font: 14pt Bahnschrift; color: black; background-color: yellow")
self.generalLayout.addWidget(self.label_bot, alignment=Qt.AlignCenter)
def setLabels(self, texttop, textbot):
# qp = QPainter(self.label_top)
self.label_top.setText(texttop)
self.label_bot.setText(textbot)
# pen = QPen(Qt.red, 3)
# qp.setPen(pen)
# qp.drawLine(10, 10, 50, 50)
# self.label_top.repaint()
class BinColCtrl:
def __init__(self, view: BinColUI):
self._view = view
self.calculateResult()
def calculateResult(self):
line_top = 'NEW LABEL TOP'
line_bottom = 'NEW LABEL BOTTOM'
self._view.setLabels(line_top, line_bottom)
def main():
"""Main function."""
# Create an instance of `QApplication`
bincol = QApplication(sys.argv)
window = BinColUI()
window.show()
BinColCtrl(view=window)
sys.exit(bincol.exec_())
if __name__ == '__main__':
main()
一般来说,QWidget(QLabel、QPushButton 等)的绘制应该只在 paintEvent 方法中完成,OP 似乎知道这一点。并且该绘画取决于小部件具有的信息,例如 QLabel 使用文本并绘制文本,OR 使用 QPixmap 并基于该像素图进行绘制。因此,在这种情况下,您必须在绘制线条的位置创建一个 QPixmap,并将该 QPixmap 传递给 QLabel 以对其进行绘制。
def setLabels(self, texttop, textbot):
pixmap = QPixmap(self.label_top.size())
pixmap.fill(Qt.transparent)
qp = QPainter(pixmap)
pen = QPen(Qt.red, 3)
qp.setPen(pen)
qp.drawLine(10, 10, 50, 50)
qp.end()
self.label_top.setPixmap(pixmap)
self.label_bot.setText(textbot)
更新:
标签上不能有文字和画线吗?
正如我在回答的开头部分所指出的那样:要么绘制文本,要么绘制 QPixmap,您不能在 QLabel 中同时进行。
我可以使用 QPainter.drawText()
画线然后在上面写文字吗?
是的,您可以使用所有方法在 QPixmap 中绘制文本:要有创意:-)。例如:
def setLabels(self, texttop, textbot):
pixmap = QPixmap(self.label_top.size())
pixmap.fill(Qt.transparent)
qp = QPainter(pixmap)
pen = QPen(Qt.red, 3)
qp.setPen(pen)
qp.drawLine(10, 10, 50, 50)
qp.drawText(pixmap.rect(), Qt.AlignCenter, texttop)
qp.end()
self.label_top.setPixmap(pixmap)
self.label_bot.setText(textbot)
在尝试使用 Python 和 PyQt5 时,我遇到了一个问题。我的 GUI 中有几个标签 (QLabel) 和图像 (QPixmap),我想在它们上面画一些东西,这取决于主程序的功能。我不知道怎么办。例如,我更改了从 class BinColUI 调用 setLabels() 的标签上的文本,然后我想在它们上面画一些东西(即 QPainter.drawLine())。我试过的没有用,没有画出任何东西。我不成功的尝试在 setLabels() 中被注释掉了。 我该怎么做?
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QVBoxLayout, QWidget
class BinColUI(QMainWindow):
def __init__(self):
super().__init__()
self.initUi()
self.createLabelTop()
self.createLabelBot()
def initUi(self):
self.setWindowTitle('Bin Collection')
self.setFixedSize(500, 500)
# self.setStyleSheet('background-color: white')
self.generalLayout = QVBoxLayout()
self._centralWidget = QWidget(self)
self.setCentralWidget(self._centralWidget)
self._centralWidget.setLayout(self.generalLayout)
def paintEvent(self, event):
self.qp = QPainter()
self.qp.begin(self)
self.drawLine(event, self.qp)
self.qp.end()
def drawLine(self, event, qp):
pen = QPen(Qt.red, 3, Qt.SolidLine)
qp.setPen(pen)
qp.drawLine(5, 5, 495, 5)
qp.drawLine(495, 5, 495, 495)
qp.drawLine(495, 495, 5, 495)
qp.drawLine(5, 495, 5, 5)
def createLabelTop(self):
self.label_top = QLabel('PLEASE WAIT')
self.label_top.setAlignment(Qt.AlignCenter)
self.label_top.setFixedSize(450, 60)
self.label_top.setStyleSheet("font: 14pt Bahnschrift; color: black; background-color: yellow")
self.generalLayout.addWidget(self.label_top, alignment=Qt.AlignCenter)
def createLabelBot(self):
self.label_bot = QLabel('PLEASE WAIT')
self.label_bot.setAlignment(Qt.AlignCenter)
self.label_bot.setFixedSize(450, 60)
self.label_bot.setStyleSheet("font: 14pt Bahnschrift; color: black; background-color: yellow")
self.generalLayout.addWidget(self.label_bot, alignment=Qt.AlignCenter)
def setLabels(self, texttop, textbot):
# qp = QPainter(self.label_top)
self.label_top.setText(texttop)
self.label_bot.setText(textbot)
# pen = QPen(Qt.red, 3)
# qp.setPen(pen)
# qp.drawLine(10, 10, 50, 50)
# self.label_top.repaint()
class BinColCtrl:
def __init__(self, view: BinColUI):
self._view = view
self.calculateResult()
def calculateResult(self):
line_top = 'NEW LABEL TOP'
line_bottom = 'NEW LABEL BOTTOM'
self._view.setLabels(line_top, line_bottom)
def main():
"""Main function."""
# Create an instance of `QApplication`
bincol = QApplication(sys.argv)
window = BinColUI()
window.show()
BinColCtrl(view=window)
sys.exit(bincol.exec_())
if __name__ == '__main__':
main()
一般来说,QWidget(QLabel、QPushButton 等)的绘制应该只在 paintEvent 方法中完成,OP 似乎知道这一点。并且该绘画取决于小部件具有的信息,例如 QLabel 使用文本并绘制文本,OR 使用 QPixmap 并基于该像素图进行绘制。因此,在这种情况下,您必须在绘制线条的位置创建一个 QPixmap,并将该 QPixmap 传递给 QLabel 以对其进行绘制。
def setLabels(self, texttop, textbot):
pixmap = QPixmap(self.label_top.size())
pixmap.fill(Qt.transparent)
qp = QPainter(pixmap)
pen = QPen(Qt.red, 3)
qp.setPen(pen)
qp.drawLine(10, 10, 50, 50)
qp.end()
self.label_top.setPixmap(pixmap)
self.label_bot.setText(textbot)
更新:
标签上不能有文字和画线吗?
正如我在回答的开头部分所指出的那样:要么绘制文本,要么绘制 QPixmap,您不能在 QLabel 中同时进行。
我可以使用 QPainter.drawText()
画线然后在上面写文字吗?
是的,您可以使用所有方法在 QPixmap 中绘制文本:要有创意:-)。例如:
def setLabels(self, texttop, textbot):
pixmap = QPixmap(self.label_top.size())
pixmap.fill(Qt.transparent)
qp = QPainter(pixmap)
pen = QPen(Qt.red, 3)
qp.setPen(pen)
qp.drawLine(10, 10, 50, 50)
qp.drawText(pixmap.rect(), Qt.AlignCenter, texttop)
qp.end()
self.label_top.setPixmap(pixmap)
self.label_bot.setText(textbot)