大佬教程收集整理的这篇文章主要介绍了在小部件上绘制形状,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要能够在另一个小部件的顶部绘制圆/线,但每次尝试时,它都会落后。我已经阅读了很多关于在小部件上使用 QPainter 的帖子,但我仍然无法让它工作。
以下是我的应用程序的一个最小示例,我只想弄清楚将paintevent函数放在哪里才能使其正常工作。
我的最终目标是让用户能够绘制像这样的热数独 - thermo
但我认为,如果我能想出如何在数独网格上绘制任何东西,我就能解决剩下的问题
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
class SudokuCell(QlineEdit):
def __init__(self,cell_size,*args,**kwargs):
super().__init__(*args,**kwargs)
self.cell_size = cell_size
Font = self.Font()
Font.setPointSize(24)
self.setFont(Font)
self.setAlignment(Qt.AlignCenter)
self.setFixedSize(cell_size,cell_sizE)
self.setautoFillBACkground(true)
class SudokuRegion(QWidget):
def __init__(self,narrow_line_wIDth,**kwargs)
self.cell_size = cell_size
self.narrow_line_wIDth = narrow_line_wIDth
layout = qgridLayout()
layout.setSpacing(narrow_line_wIDth)
layout.setContentsmargins(0,0)
self.setLayout(layout)
for i in range(3):
for j in range(3):
new_cell = SudokuCell(cell_size,objectname=f"C{i}{j}")
layout.addWidget(new_cell,i,j)
class SudokuGrID(QWidget):
def __init__(self,wIDe_line_wIDth,**kwargs)
self.cell_size = cell_size
self.wIDe_line_wIDth = wIDe_line_wIDth
self.narrow_line_wIDth = narrow_line_wIDth
layout = qgridLayout()
layout.setContentsmargins(wIDe_line_wIDth,0)
layout.setSpacing(wIDe_line_wIDth)
self.setLayout(layout)
for i in range(3):
for j in range(3):
new_region = SudokuRegion(cell_size,objectname=f"Region{i * 3 + j}")
layout.addWidget(new_region,j)
class MainWindow(QMainWindow):
def __init__(self,window_w,window_h,orthogonal_intersection_size,narrow_line_wIDth):
super().__init__()
self.window_w = window_w
self.window_h = window_h
self.orthogonal_intersection_size = orthogonal_intersection_size
self.cell_size = cell_size
self.wIDe_line_wIDth = wIDe_line_wIDth
self.narrow_line_wIDth = narrow_line_wIDth
# a sudoku grID is exactly this large. Google A sudoku grID if you dont understand
self.frame_size = 9 * cell_size + 4 * wIDe_line_wIDth + 6 * narrow_line_wIDth
self.initUi()
def initUi(self):
self.setwindowtitle("Sudoku Solver")
self.setGeometry(100,100,self.window_w,self.window_h)
Widget = QWidget(self)
self.setCentralWidget(Widget)
hor_Box = QHBoxLayout()
Widget.setLayout(hor_BoX)
self.frame = qframe(Widget)
self.frame.setFixedSize(self.frame_size,self.frame_sizE)
self.frame.setStyleSheet(".qframe {BACkground-color: black}")
self.grID = SudokuGrID(self.cell_size,self.wIDe_line_wIDth,self.narrow_line_wIDth,self.framE)
hor_Box.addWidget(self.framE)
# other Widgets are added to the hor_Box later but arent important for this question
self.show()
def main():
app = QApplication(sys.argv)
window = MainWindow(
window_w=1000,window_h=750,orthogonal_intersection_size=25,cell_size=80,wIDe_line_wIDth=8,narrow_line_wIDth=2
)
window.show()
app.exec_()
if __name__ == "__main__":
main()
您可以在 SudokuCell 或 SudokuGrid 中重新实现 paintEvent
,但在任何一种情况下,SudokuCell 都需要具有透明背景,以便热绘图将绘制在除 QLineEdit 文本编辑器之外的所有内容之上。我选择了数独细胞。
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class SudokuCell(QLineEdit):
def __init__(self,cell_size,*args,**kwargs):
super().__init__(*args,**kwargs)
self.cell_size = cell_size
font = self.font()
font.setPointSize(24)
self.setFont(font)
self.setAlignment(Qt.AlignCenter)
self.setFixedSize(cell_size,cell_sizE)
self.setAutoFillBACkground(true)
self.setStyleSheet('''
SudokuCell {
BACkground-color: rgba(0,0);
border: none;
}''')
self.line = QPainterPath()
self.ellipse = false
def paintEvent(self,event):
qp = QPainter(self)
qp.setPen(Qt.NoPen)
qp.setBrush(Qt.whitE)
qp.drawRect(self.rect())
s = self.cell_size
if self.ellipse:
qp.setRenderHint(QPainter.Antialiasing)
qp.setBrush(Qt.gray)
qp.drawEllipse(self.rect().center(),s / 2.5,s / 2.5)
qp.setPen(QPen(Qt.gray,s / 2,Qt.SolidLine,Qt.FlatCap,Qt.MiterJoin))
qp.drawPath(self.linE)
super().paintEvent(event)
请注意,super().paintEvent(event)
在自定义绘画之后被调用,因此文本编辑器将在任何绘画的顶部可见。如果背景为白色,它将覆盖自定义绘画。 SudokuGrid 类具有向由行和列指定的任何单元格添加线或椭圆的方法。
class SudokuGrid(QWidget):
...
def cell(self,row,col):
region = self.layout().itemAtPosition(row // 3,col // 3).widget()
return region.layout().itemAtPosition(row % 3,col % 3).widget()
def add_ellipse(self,col):
self.cell(row,col).ellipse = True
def add_line(self,col,*linE):
path = QPainterPath(QPointF(*line[0]) * self.cell_sizE)
for point in line[1:]:
path.lineTo(QPointF(*point) * self.cell_sizE)
self.cell(row,col).line = path
*line
的 SudokuGrid.add_line()
参数旨在是 0-1 范围内的元组,作为定义 QPainterPath 行元素的简单键(类似于渐变的元素 — 0 = 左/上,0.5 = 中心,1 = 右/下)。
class MainWindow(QMainWindow):
def __init__(self,window_w,window_h,orthogonal_intersection_size,wide_line_width,narrow_line_width):
super().__init__()
self.window_w = window_w
self.window_h = window_h
self.orthogonal_intersection_size = orthogonal_intersection_size
self.cell_size = cell_size
self.wide_line_width = wide_line_width
self.narrow_line_width = narrow_line_width
# a sudoku grid is exactly this large. Google A sudoku grid if you dont understand
self.frame_size = 9 * cell_size + 4 * wide_line_width + 6 * narrow_line_width
self.initUi()
self.grid.add_line(0,(0.25,0.5),(1,0.5))
self.grid.add_line(0,1,(0,2,(0.5,1))
self.grid.add_line(1,0),1))
self.grid.add_line(2,0.5))
self.grid.add_ellipse(2,2)
这里是它在 MainWindow 中的使用方式。当然,您可以采用更适合您的程序的完全不同的方式将线条和椭圆添加到网格中,主要目的是展示如何在“小部件顶部”实现绘画。
以上是大佬教程为你收集整理的在小部件上绘制形状全部内容,希望文章能够帮你解决在小部件上绘制形状所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。