嘛……实验室要用所以写的,存档一下……实验上还有些问题所以以后还会有所修改
Painter.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'E:\实验室\FCController\Qt_Designer\DrawPoints.ui'
#
# Created by: PyQt5 UI code generator 5.12
#
# WARNING! All changes made in this file will be lost!
import sys
import os
from PyQt5.QtCore import QRect, Qt
from PyQt5.QtGui import QIcon, QFont, QPainter, QPen, QColor
from PyQt5.QtWidgets import QWidget, QPushButton, QLineEdit, QLabel, QMessageBox, QFileDialog, QApplication
sys.path.append('.')
import savepoint as PtoCSV
import basepaint
class ParaError(Exception):
def __init__(self, ErrorInfo):
super().__init__(self)
self.errorinfo=ErrorInfo
def __str__(self):
return self.errorinfo
class Popup(QWidget):
def __init__(self, func, parent_window, para_list):
QWidget.__init__(self)
self.setWindowOpacity(0.9)
self.process = func
self.pw = parent_window
self.setWindowTitle("Parameters")
self.setWindowIcon(QIcon("mspaint.ico"))
self.para_num = len(para_list)
self.Button = QPushButton("Draw!", self)
self.Button.setGeometry(QRect(20+self.para_num*120, 20, 60, 70))
self.Button.setFont(QFont("Microsoft YaHei"))
self.Button.clicked.connect(self.run_func)
self.para = []
self.label = []
for i in range(self.para_num):
# 参数输入框
self.para.append(QLineEdit(self))
self.para[i].setGeometry(QRect(20+i*120, 50, 100, 40))
# 参数描述
self.label.append(QLabel(self))
self.label[i].setGeometry(QRect(20+i*120, 20, 100, 40))
self.label[i].setAlignment(Qt.AlignHCenter)
self.label[i].setText(para_list[i])
self.label[i].setFont(QFont("Microsoft YaHei"))
def run_func(self, event):
try:
para = []
for i in range(self.para_num):
para.append(int(self.para[i].text()))
if(para[i] <= 0):
raise ParaError("Invalid Parameters!")
self.pw.Image = self.process(self.pw.Image, self.pw.nx, self.pw.ny, para)
self.close()
except Exception as e:
#self.setWindowTitle("Parameters - "+str(e))
QMessageBox.critical(self, "Invalid Parameters!", str(e),)
class SimpleDrawingBoard(QWidget):
def __init__(self):
super(SimpleDrawingBoard, self).__init__()
Width = 1100
Height = 970
self.update_pic_range(BackgroudStartX=100, BackgroudEndX=1028, \
BackgroudStartY=20, BackgroudEndY=948, Divider=32)
#是否允许拖曳绘制,默认打开
self.EnableDragDraw = True
#resize设置宽高,move设置位置
self.resize(Width, Height)
self.move(100, 10)
self.setWindowTitle("DrawPoint")
self.setWindowIcon(QIcon("mspaint.ico"))
#保存按钮
self.SaveButton = QPushButton("Save", self)
self.SaveButton.setGeometry(QRect(10, 20, 80, 40))
self.SaveButton.clicked.connect(self.isSaveButtonClicked)
self.SaveButton.setFont(QFont("Microsoft YaHei"))
#清除按钮
self.CleanButton = QPushButton("Clean", self)
self.CleanButton.setGeometry(QRect(10, self.YE-40, 80, 40))
self.CleanButton.clicked.connect(self.isCleanButtonClicked)
self.CleanButton.setFont(QFont("Microsoft YaHei"))
#增减按钮
self.divider_double_button = QPushButton("+", self)
self.divider_double_button.setGeometry(QRect(10, 80, 40, 40))
self.divider_double_button.clicked.connect(self.double_grid)
self.divider_half_button = QPushButton("-", self)
self.divider_half_button.setGeometry(QRect(50, 80, 40, 40))
self.divider_half_button.clicked.connect(self.half_grid)
#几个常用图形按钮
self.circle_button = QPushButton("Cirle", self)
self.circle_button.setGeometry(QRect(10, 180, 80, 40))
self.circle_button.clicked.connect(self.circlebutton_clicked)
self.circle_button.setFont(QFont("Microsoft YaHei"))
self.rect_button = QPushButton("Rect", self)
self.rect_button.setGeometry(QRect(10, 280, 80, 40))
self.rect_button.clicked.connect(self.rectbutton_clicked)
self.rect_button.setFont(QFont("Microsoft YaHei"))
self.ellipse_button = QPushButton("Ellipse", self)
self.ellipse_button.setGeometry(QRect(10, 380, 80, 40))
self.ellipse_button.clicked.connect(self.ellipsebutton_clicked)
self.ellipse_button.setFont(QFont("Microsoft YaHei"))
self.ellipse_button.setDisabled(True)
self.setMouseTracking(True)
#设置两个变量接收移动中的点的x、y坐标
self.pos_x = 0
self.pos_y = 0
self.Current_pos_x = 0
self.Current_pos_y = 0
def OutRange(self):
x = self.Current_pos_x
y = self.Current_pos_y
if(x>=self.XE or x<=self.XS or y>=self.YE or y<=self.YS):
return True
else:
return False
def update_pic_range(self, BackgroudStartX=100, BackgroudStartY=20, BackgroudEndX=1028, BackgroudEndY=948, Divider=16):
BackgroudEndX = BackgroudStartX + (BackgroudEndX-BackgroudStartX)//Divider*Divider
BackgroudEndY = BackgroudStartY + (BackgroudEndY-BackgroudStartY)//Divider*Divider
self.XS = BackgroudStartX
self.YS = BackgroudStartY
self.XE = BackgroudEndX
self.YE = BackgroudEndY
self.Divider = Divider
self.nx = (self.XE-self.XS)//self.Divider
self.ny = (self.XE-self.XS)//self.Divider
#初始化格子绘制情况
self.Image = [[0]*self.ny for i in range(self.nx)]
#设置初始背景格子绘点
self.GridMatrix = []
#横向线条
for i in range(0, self.ny+1):
self.GridMatrix.append((self.XS, self.YS+i*Divider, self.XE, self.YS+i*Divider))
#纵向线条
for i in range(0, self.nx+1):
self.GridMatrix.append((self.XS+i*Divider, self.YS, self.XS+i*Divider, self.YE))
def CurrentPos(self):
return ((self.Current_pos_x-self.XS)//self.Divider, (self.Current_pos_y-self.YS)//self.Divider)
def BackgroundPaint(self):
'''
绘制格子,将当前鼠标指向的格子染蓝,将点过的格子染红
'''
Matrix = self.GridMatrix
painter = QPainter()
painter.begin(self)
pen = QPen(QColor(200,200,200), 1, Qt.SolidLine)
painter.setPen(pen)
painter.setBrush(QColor(100,149,237)) # #6495ED Cornflower blue
# Draw the block that mouse is on.
if not self.OutRange():
mouseblock = self.CurrentPos()
painter.drawRect(self.XS+mouseblock[0]*self.Divider, self.YS+mouseblock[1]*self.Divider, self.Divider, self.Divider)
for i in range(0, len(Matrix)):
points = Matrix[i]
painter.drawLine(points[0],points[1],points[2],points[3])
# Draw Image
painter.setBrush(QColor(255,0,0))
for i in range(0,self.nx):
for j in range(0,self.ny):
if(self.Image[i][j]==1):
painter.drawRect(self.XS+i*self.Divider, self.YS+j*self.Divider, self.Divider, self.Divider)
painter.end()
def paintEvent(self, event):
'''
当事件触发更新绘图时候,调用BackgroundPaint方法绘制一次区域
'''
self.BackgroundPaint()
def isSaveButtonClicked(self, event):
'''
按下保存按键
'''
filename, ok = QFileDialog.getSaveFileName(QApplication.desktop(), 'save points', os.getcwd(), '*.csv')
if(ok):
pointlist = PtoCSV.covert_pmatrix_to_csv(self.Image)
PtoCSV.write_points_to_file(filename, pointlist, (self.nx, self.ny))
def isCleanButtonClicked(self, event):
'''
按下清除按键
'''
self.Image = [[0]*((self.YE-self.YS)//self.Divider) for i in range(((self.XE-self.XS)//self.Divider))]
self.update()
def half_grid(self, event):
if((self.nx==1) or (self.ny==1)):
pass
else: self.update_pic_range(Divider=self.Divider*2)
self.update()
def double_grid(self, event):
if(self.Divider==4):
pass
else: self.update_pic_range(Divider=self.Divider//2)
self.update()
def circlebutton_clicked(self, event):
self.parameter_window = Popup(basepaint.circle, self, ['r', 'theta/°', 'n'])
self.parameter_window.move(200, 200)
self.parameter_window.setFixedSize(100+120*3, 110)
self.parameter_window.show()
def rectbutton_clicked(self, event):
self.parameter_window = Popup(basepaint.rect, self, ['na', 'nb', 'delta'])
self.parameter_window.move(200, 200)
self.parameter_window.setFixedSize(100+120*3, 110)
self.parameter_window.show()
def ellipsebutton_clicked(self, event):
a = 10
b = 5
delta = 1
self.Image = basepaint.ellipse(self.Image, self.nx, self.ny, a, b, delta)
def mousePressEvent(self, event):
'''
点击鼠标事件
'''
# self.pos_x = event.pos().x()
# self.pos_y = event.pos().y()
if self.OutRange():
return
if (event.buttons() == Qt.LeftButton):
#左键点击,染色
tmp = self.CurrentPos()
self.Image[tmp[0]][tmp[1]] = 1
if (event.buttons() == Qt.RightButton):
#右键点击,取消染色
tmp = self.CurrentPos()
self.Image[tmp[0]][tmp[1]] = 0
#print(self.Image)
self.update() #重新绘制
def mouseMoveEvent(self, event):
'''
鼠标移动事件
'''
self.Current_pos_x = event.pos().x()
self.Current_pos_y = event.pos().y()
if(self.OutRange()):
PositionString = "x=NA y=NA"
else:
tmp = self.CurrentPos()
tmp = (tmp[0]+1,tmp[1]+1)
PositionString = "x=%d y=%d" % tmp
if(self.EnableDragDraw):
if (event.buttons() == Qt.LeftButton):
#左键点击,染色
#触摸板上容易误操作,仅保留连续取消染色
tmp = self.CurrentPos()
#self.Image[tmp[0]][tmp[1]] = 1
if (event.buttons() == Qt.RightButton):
#右键点击,染色
tmp = self.CurrentPos()
self.Image[tmp[0]][tmp[1]] = 0
self.setWindowTitle("DrawPoint : "+PositionString)
self.update()
#self.PositionLabel.setText("%d.%d" % (self.Current_pos_x, self.Current_pos_y))
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
MainWindow = SimpleDrawingBoard()
MainWindow.show()
sys.exit(app.exec_())
basepaint.py
#!/usr/bin/env python3
#coding=utf-8
import numpy as np
import os
import sys
def rect(img, nx, ny, parameters):
na, nb, delta = parameters
draw = np.zeros((nx,ny), dtype=np.int)
center_x = nx//2
center_y = ny//2
for i in range(na):
for j in range(nb):
if((center_x+i*delta >= nx) or (center_y+i*delta >= ny)):
continue
else:
draw[center_x+i*delta][center_y+j*delta]=1
draw[center_x+i*delta][center_y-j*delta]=1
draw[center_x-i*delta][center_y+j*delta]=1
draw[center_x-i*delta][center_y-j*delta]=1
return (img+draw)!=0
def circle(img, nx, ny, parameters):
r, theta, n = parameters
draw = np.zeros((nx,ny), dtype=np.int)
center_x = nx//2
center_y = ny//2
for i in range(n):
shift = r*i
if((center_x+shift)>=nx or (center_y+shift)>=ny):
continue
else:
rotator = 0
while(rotator < 2*np.pi):
new_x = int(round(center_x + shift*np.cos(rotator)))
new_y = int(round(center_y + shift*np.sin(rotator)))
#round returns a xx.0 :(
#print(new_x, new_y)
draw[new_x][new_y] = 1
rotator = rotator + theta*np.pi/180
return (img+draw)!=0
def ellipse(img, nx, ny, parameters):
return img
savepoint.py
#!/usr/bin/env python3
#coding=utf8
import numpy as np
# 目标分辨率,使用前需改成PZT对应行程,或者注释掉这两行,在import的部分指定
_TARGET_HEIGT = 125*1000
_TARGET_WIDTH = 125*1000
def covert_pmatrix_to_csv(matrix):
# matrix为一个二维数组,仅有0与非0区分,非0表示打点
height, width = np.shape(matrix)
point_list = []
for i in range(height):
for j in range(width):
if(matrix[i][j]==0):
pass
else: point_list.append((i,j))
return point_list
def write_points_to_file(filename, point_list, resolution):
# filename为一个字符串,表示存储的文件名
# point_list是一个list类,每个元素是一个tuple,表示坐标
# resolution是一个tuple,表示point_list范围(绘图的分辨率)
if(filename[-3:].lower() != "csv"):
filename=filename+".csv"
else:
filename=filename[:-3]+filename[-3:].lower()
# :P随手转成小写后缀名……
resx = resolution[0]
resy = resolution[1]
if(resolution[0]&1 == 1):
resx = resolution[0]-1
if(resolution[1]&1 == 1):
resy = resolution[0]-1
with open(filename, 'w') as f:
for i in point_list:
real_position = (i[0]/resx*_TARGET_WIDTH - _TARGET_WIDTH/2, i[1]/resy*_TARGET_HEIGT - _TARGET_WIDTH/2)
f.write('%f, %f\n'%real_position)
return
One comment
不错不错,我喜欢看 https://www.237fa.com/