SWT:GC.drawPolygon

本文介绍了使用GC类中的drawPolygon方法绘制闭合多边形的技术。与drawPolyline不同之处在于,drawPolygon会将最后一个点与第一个点相连形成闭合图形。

GC.drawPolygon(int[] pointArray);与drawPolyline(int[])是类似的,唯一区别在于最后一个点和第一个点是连接的。

 

绘制闭合的多边形。

from Form6 import * import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QColorDialog, QDialog, QLabel from PyQt5.QtGui import QPainter,QPixmap,QPen,QBrush,QColor,QPolygon,QPalette,QPolygonF from PyQt5.QtCore import Qt,QPoint class Canvas(QLabel): choose_btn=-1 choose_fill_color=QColor() def __init__(self): super().__init__() canvas = QPixmap(1200,800) canvas.fill(QColor('gray')) self.setPixmap(canvas) self.pen_color = QColor() self.brush = QBrush() def mousePressEvent(self, event): painter = QPainter(self) pen = painter.pen() pen.setWidth(2) pen.setColor(self.pen_color) painter.setPen(pen) if self.choose_btn==0: #直线 painter.drawLine(50,50,200,50) pen.setstyle(Qt.DashLine)#虚线 painter.setPen(pen) painter.drawLine(50, 100, 200,100) pen.setcolor(Qt.darkMagenta)#颜色 pen.setStyLe(Qt.DashDotLine)#点划线 painter.setPen(pen) painter.drawLine(50, 150,200,150) pen.setColor(Qt.blue)#顔色 pen.setStyLe(Qt.SolidLine)#实线 painter.setPen(pen) painter.drawLine(50, 200,200,200) elif self.choose_btn==1: #矩形 painter.drawRect(100,100,200,100) elif self.choose_btn==2: #椭圆形 painter.drawEllipse(120,120,150,100) #绘制多边形 elif self.choose_btn==3: points = [QPoint(100, 100),QPoint(300, 150),QPoint(350, 250),QPoint(200, 300),QPoint(120, 230)] painter.drawPolygon(QPolygon(points)) elif self.choose_btn==4: painter.setBrush(self.choose_fill_color) painter.drawRect(100, 100, 200, 100) elif self.choose_btn==5: painter.setBrush(self.choose_fill_color) painter.drawEllipse(120, 120, 150, 100) elif self.choose_btn==6: points = [QPoint(100, 100),QPoint(300, 150),QPoint(350, 250),QPoint(200, 300),QPoint(120, 230)] painter.setBrush(self.choose_fill_color) painter.drawPolygon(QPolygonF(points)) painter.end() self.update() class MyDialog(QDialog, Ui_Dialog): def __init__(self, parent=None): super(MyDialog, self).__init__(parent) self.setupUi(self) self.canvas = Canvas() self.buju=QVBoxLayout(self.groupBox) self.buju.addWidget(self.canvas) def plot_line(self): self.canvas.choose_btn =0 def plot_rect(self): self.canvas.choose_btn =1 def plot_Eli(self): self.canvas.choose_btn =2 def plot_duo(self): self.canvas.choose_btn =3 def plot_fill_Rect(self): self.canvas.choose_btn =4 def plot_fill_Eli(self): self.canvas.choose_btn =5 def plot_fill_duo(self): self.canvas.choose_btn =6 def showDialog(self): dialog = QColorDialog() dialog.setOption(QColorDialog.ShowAlphaChannel, on=True) if dialog.exec_() == QDialog.Accepted: color = dialog.selectedColor() if color.isValid(): self.canvas.choose_fill_color = color self.btn_fill_color.setStyleSheet("background-color: {};".formate(color.name(QColor.HexArgb))) if __name__ =='__main__': app = QApplication(sys.argv) form = MyDialog() #按钮连接槽函数 form.btn_Line.clicked.connect(form.plot_line) form.btn_juxing.clicked.connect(form.plot_Rect) form.btn_tuoyuan.clicked.connect(form.plot_Eli) form.btn_duobian.clicked.connect(form.plot_duo) form.btn_fill_juxing.clicked.connect(form.plot_fill_Rect) form.btn_fill_tuoyuan.clicked.connect(form.plot_fill_Eli) form.btn_fill_duobian.clicked.connect(form.plot_fill_duo) form.btn_fill_color.clicked.connect(form.showDialog) form.show() sys.exit(app. exec_())
07-17
import sys from PyQt5.QtGui import QPen, QPainter from PyQt5.QtCore import Qt, QPointF from PyQt5.QtWidgets import QDialog, QApplication, QWidget from Form4 import * import matplotlib.pyplot as plt from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas import random import numpy as np class DrawingWidget(QWidget): def __init__(self, parent=None): super(DrawingWidget, self).__init__(parent) self.vertices = [] self.drawing_enabled = False def paintEvent(self, event): painter = QPainter(self) painter.setPen(QPen(Qt.red, 3, Qt.SolidLine)) painter.setRenderHint(QPainter.Antialiasing) ploygon = QtGui.QPolygonF(self.vertices) painter.drawPolygon(ploygon) for vertex in self.vertices: painter.drawEllipse(vertex, 5, 5) vertex_str = f"({vertex.x():.4f},{vertex.y():.4f})"#将列表中的xy坐标值变成字符串。并保留4位小数 painter.drawText(vertex + QPointF(10,-10),vertex_str)#在坐标的位置+10,-10右上角显示坐标值 def mousePressEvent(self, event): if self.drawing_enabled: if event.button() == Qt.LeftButton: pos = event.pos() self.vertices.append(QPointF(pos.x(), pos.y())) self.update() self.parent().updateArea() elif event.button() == Qt.RightButton: self.vertices = []#清除所有顶点坐标 self.update() self.parent().updateArea() class MatplotlibWidget(FigureCanvas): def __init__(self, parent=None): self.fig, self.ax = plt.subplots() super(MatplotlibWidget, self).__init__(self.fig) self.setParent(parent) self.ax.set_xlim(0, 100) self.ax.set_ylim(0, 100) def plot_points(self, points): self.ax.clear() self.ax.scatter(*zip(*points)) self.draw() def plot_polygon(self, points): self.ax.plot(*zip(*points)) points.append(points[0]) self.ax.plot(*zip(*points), marker='0') for x,y in points: self.ax.text(x,y,f"({x:.2f},{y:.2f})", fontsize=9, ha='right') self.draw() class TaskTest(QDialog, Ui_Form): def __init__(self): super(TaskTest, self).__init__() self.setupUi(self) self.drawing_widget = DrawingWidget(self) self.drawing_widget.setGeometry(10, 10, 600, 600) self.matplotlib_widget = MatplotlibWidget(self) self.matplotlib_widget.setGeometry(625, 20, 550, 600) def enableDrawing(self): self.drawing_widget.drawing_enabled = True self.drawing_widget.vertices = [] self.drawing_widget.update() self.updateArea() def calculatePolygonArea(self, polygon): area = 0.0 n = polygon.size() for i in range(n): j = (i + 1) % n area += polygon[i].x() * polygon[j].y() area -= polygon[j].x() * polygon[i].y() area = abs(area) / 2.0 return area def updateArea(self): polygon = self.drawing_widget.vertices area = self.calculatePolygonArea(polygon) self.matplotlib_widget.plot_points(polygon) self.matplotlib_widget.plot_polygon(polygon) self.area_label.setText(f"面积:{area:.2f}") self.matplotlib_widget.draw() self.matplotlib_widget.update() self.matplotlib_widget.show() def generate_random_points(self): try: num_points = int(self.suijidianlineEdit_2.toPlainText()) x_range = int(self.xlineEdit_3.toPlainText()) y_range = int(self.ylineEdit_4.toPlainText()) self.points = [(random.uniform(0, x_range), random.uniform(0, y_range)) for _ in range(num_points)] self.matplotlib_widget.plot_points(self.points) # 更新显示 self.textBrowser.clear() self.textBrowser.append(f"随机点个数: {num_points}") self.textBrowser.append(f"x_max: {x_range}, y_max: {y_range}") except Exception as e: self.textBrowser.append(f"错误: {str(e)}") def generate_polygon(self): centroid = np.mean(self.points, axis=0) def angle_from_centroid(point): return np.arctan2(point[1] - centroid[1], point[0] - centroid[0]) sorted_points = sorted(self.points, key=angle_from_centroid) self.matplotlib_widget.plot_polygon(sorted_points) def graham_scan(self, points): points = sorted(points, key=lambda p: (p[0], p[1])) lower = [] for p in points: while len(lower) >= 2 and self.cross(lower[-2], lower[-1], p) <= 0: lower.pop() lower.append(tuple(p)) upper = [] def cross(self, o, a, b):# 向量叉乘 (a-o) × (b-o) return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]) def calculate_area(self, points):# 用鞋带公式计算面积 area = 0.0 n = len(points) for i in range(n): j = (i + 1) % n area += points[i][0] * points[j][1] - points[j][0] * points[i][1] return abs(area / 2.0) def calculate_convex_hull(self): if hasattr(self, 'points') and self.points: points = np.array(self.points) hull = self.graham_scan(points) self.matplotlib_widget.plot_polygon(hull) area = self.calculate_area(hull) self.mianji2lineEdit_5.setPlainText(f"{area:.2f}") if __name__ == "__main__": QApplication.setAttribute(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) app = QApplication(sys.argv) s = TaskTest() s.show() app.exec_() s.huizhipushButton.clicked.connect(s.ensbleDrawing) s.suijidianpushButton_2.clicked.connect(s.generate_random_points) s.duibianxingpushButton_3.clicked.connect(s.generate_polygon) s.tubaopushButton_4.clicked.connect(s.calculate_convex_hull) sys.exit(app.exec_()) 绘制多边形不显示鼠标点击的点
07-17
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值