Skip to content

Commit

Permalink
更新
Browse files Browse the repository at this point in the history
  • Loading branch information
mibino authored Mar 2, 2024
1 parent f01600f commit d06c8a9
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 187 deletions.
27 changes: 23 additions & 4 deletions homepage.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import wx
from tkinter import *
from tkinter import messagebox
from tkinter.colorchooser import askcolor
from paint import *

class homepage(wx.Frame):
Expand All @@ -20,13 +23,29 @@ def __init__(self):
SpaceSim_字体 = wx.Font(16,74,90,400,False,'Microsoft YaHei UI',28)
self.SpaceSim.SetFont(SpaceSim_字体)
self.SpaceSim.Bind(wx.EVT_BUTTON,self.SpaceSim_按钮被单击)

self.Physics = wx.Button(self.Homepage,size=(120, 80),pos=(0, 200),label='物理学习',name='button')
Physics_字体 = wx.Font(16,74,90,400,False,'Microsoft YaHei UI',28)
self.Physics.SetFont(Physics_字体)
self.Physics.Bind(wx.EVT_BUTTON,self.Physics_按钮被单击)
self.About = wx.Button(self.Homepage,size=(120, 80),pos=(0, 280),label='关于',name='button')
About_字体 = wx.Font(16,74,90,400,False,'Microsoft YaHei UI',28)
self.About.SetFont(Physics_字体)
self.About.Bind(wx.EVT_BUTTON,self.About_按钮被单击)

def ToPaint_按钮被单击(self,event):
self.frame = SketchFrame()
self.frame.Show(True)
SketchFrame.Show(True)
root = Tk()
root.title('画图窗口')
root.attributes("-fullscreen", True)
app = Paint(master=root)
root.mainloop()


def SpaceSim_按钮被单击(self,event):
exec(open("space.py", encoding='utf-8', errors='ignore').read())


def Physics_按钮被单击(self,event):
exec(open("physics.py", encoding='utf-8', errors='ignore').read())

def About_按钮被单击(self,event):
wx.MessageBox("一个普通的教学工具软件\n本软件完全开源\n任何人都可查看和贡献源代码\n本软件遵循Apache License 2.0\n官网:https://mibino.github.io/eteach/", "关于 ETeach" ,wx.OK | wx.ICON_INFORMATION)
314 changes: 131 additions & 183 deletions paint.py
Original file line number Diff line number Diff line change
@@ -1,191 +1,139 @@
import wx
from tkinter import *
from tkinter import messagebox
from tkinter.colorchooser import askcolor

win_width = 800
win_height = 650
bgcolor = '#ffffff'

# 原参考代码:https://blog.csdn.net/weixin_44252933/article/details/122296987

BUFFERED = True # 使用缓冲法,即 double buffered
# BUFFERED = False # 使用直接法

class Myline():
"""笔画类,包含笔迹的颜色、粗细、样式、数据点"""
def __init__(self, color, thick, style, datas):
self.pen_msg = (color, thick, style)
self.datas = datas

class SimpleSketchWindow(wx.Window):
"""画板缓冲窗口"""
def __init__(self, *args, **kw):
super().__init__(*args, **kw, size=(800,600))

self.cur_pos = (0,0) # 当前鼠标位置
self.cur_line = [] # 当前笔画 [(x1, y1), (x2, y2), ... ,(xn,yn)]
self.lines = [] # 所有笔画 [line1, line2, ..., line m]

self.pen_color = 'BLACK' # 笔迹颜色
self.pen_thick = 4 # 笔迹粗细
self.pen_style = wx.PENSTYLE_SOLID # 笔类型

# 设置缓存区
if BUFFERED:
self.buffer = None
self.InitBuffer()

# 设置背景颜色
self.SetBackgroundColour('white')
# 设置鼠标图标为“铅笔”
self.SetCursor(wx.Cursor(wx.CURSOR_PENCIL))

# 绑定事件
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
self.Bind(wx.EVT_MOTION, self.OnMotion)
self.Bind(wx.EVT_PAINT, self.OnPaint) # 触发时机:窗口大小变换
self.Bind(wx.EVT_SIZE, self.OnSize)





def InitBuffer(self):
"""初始化缓冲区"""
if BUFFERED:
# 设置缓冲区与窗口的大小一致
size = self.GetClientSize()
self.buffer = wx.Bitmap(*size)
# 第一个参数为None,相当于初始化 buffer
dc = wx.BufferedDC(None, self.buffer)
else:
# 直接获得当前窗口的设别上下文
dc = wx.ClientDC(self)

# 默认的绘画:绘制已存在的笔迹
self.DefaultDrawing(dc)

# 添加你的绘画
self.DoMyDrawing(dc)

def DefaultDrawing(self, dc:wx.DC):
"""默认绘画"""

# 设置背景颜色
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear() # 使用当前背景刷来清除设备上下文。

# 绘制所有的笔画
self.DrawAllLines(dc)

def DrawAllLines(self, dc:wx.DC):
"""绘制所有的直线"""
for line in self.lines:
# 设置笔画
pen = wx.Pen(*line.pen_msg)
dc.SetPen(pen)
# 绘制直线
for i in range(1, len(line.datas)):
coord = (line.datas[i-1].x, line.datas[i-1].y,
line.datas[i].x, line.datas[i].y)
dc.DrawLine(*coord)

def DoMyDrawing(self, dc:wx.DC):
"""需要继承此类,然后重构此函数"""
pass

# ====================================================================
# 事件响应函数
# ====================================================================
def OnSize(self, event):
"""响应窗口大小改变"""

# 每次窗口大小变换,都需要重新设置缓冲区大小
self.InitBuffer()

print("OnSize")
event.Skip()

def OnPaint(self, event):
"""响应Paint Event"""

if BUFFERED:
wx.BufferedPaintDC(self, self.buffer)
else:
dc = wx.PaintDC(self)
# 重新绘制
self.DefaultDrawing(dc)
self.DoMyDrawing(dc)

print("OnPaint")
event.Skip()

def OnLeftDown(self, event:wx.MouseEvent):
"""鼠标左键按下,记录起始坐标"""

# 获得当前鼠标位置
self.cur_pos = event.GetPosition()
# 新笔画的起点
self.cur_line = []
self.cur_line.append(self.cur_pos)

print("Left Down: (%d, %d)" % (self.cur_pos.x, self.cur_pos.y))
event.Skip()

def OnLeftUp(self, event:wx.MouseEvent):
"""鼠标左键松开,记录当前笔画"""

if len(self.cur_line) > 1:
self.lines.append(Myline(
self.pen_color, self.pen_thick, self.pen_style, self.cur_line))

print("Left Up: (%d, %d)" % (self.cur_pos.x, self.cur_pos.y))
event.Skip()

def OnMotion(self, event:wx.MouseEvent):
"""鼠标移动(左键拖动)"""
if event.Dragging() and event.LeftIsDown():
# 更新鼠标的坐标
pre_pos = self.cur_pos
self.cur_pos = event.GetPosition()
self.cur_line.append(self.cur_pos)
# 设置缓冲区
if BUFFERED:
# 设置缓冲区,当dc销毁时,将 buffer 复制到当前窗口上
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
else:
# 直接获得当前窗口的设别上下文
dc = wx.ClientDC(self)
# 绘制直线
pen = wx.Pen(self.pen_color, self.pen_thick, self.pen_style)
dc.SetPen(pen)
coord = (pre_pos.x, pre_pos.y, self.cur_pos.x, self.cur_pos.y)
dc.DrawLine(*coord)

print("Drawing:", coord)

event.Skip()


class SketchWindow(SimpleSketchWindow):

def __init__(self, *args, **kw):
super().__init__(*args, **kw)

def DoMyDrawing(self, dc: wx.DC):
"""绘制自定义内容"""



class Paint(Frame):
"""一个经典的GUI写法"""

def __init__(self, master=None):
"""初始化方法"""
super().__init__(master) # 调用父类的初始化方法
self.x = 0
self.y = 0
self.fgcolor = 'black'
self.lastdraw = 0
self.start_flag = False
self.master = master
self.pack()
self.createWidget()

def createWidget(self):
"""创建画图区域"""
self.drawpad = Canvas(self, width=win_width, height=win_height, bg=bgcolor)
self.drawpad.pack()
# 创建按钮
self.btn_start = Button(self, name='start', text='开始')
self.btn_start.pack(side='left', padx=10)
self.btn_pen = Button(self, name='pen', text='画笔')
self.btn_pen.pack(side='left', padx=10)
self.btn_rect = Button(self, name='rect', text='矩形')
self.btn_rect.pack(side='left', padx=10)
self.btn_clear = Button(self, name='clear', text='清屏')
self.btn_clear.pack(side='left', padx=10)
self.btn_erasor = Button(self, name='erasor', text='橡皮擦')
self.btn_erasor.pack(side='left', padx=10)
self.btn_line = Button(self, name='line', text='直线')
self.btn_line.pack(side='left', padx=10)
self.btn_line_arrow = Button(self, name='line_arrow', text='箭头直线')
self.btn_line_arrow.pack(side='left', padx=10)
self.btn_color = Button(self, name='color', text='颜色')
self.btn_color.pack(side='left', padx=10)
self.btn_quit = Button(self, name='quit', text='退出')
self.btn_quit.pack(side='left', padx=10)
# 绑定事件
self.btn_line.bind('<Button-1>', self.eventManager) # 点击按钮事件
self.btn_line_arrow.bind('<Button-1>', self.eventManager) # 点击按钮事件
self.btn_rect.bind('<Button-1>', self.eventManager) # 点击按钮事件
self.btn_pen.bind('<Button-1>', self.eventManager) # 点击按钮事件
self.btn_erasor.bind('<Button-1>', self.eventManager) # 点击按钮事件
self.btn_clear.bind('<Button-1>', self.eventManager) # 点击按钮事件
self.btn_color.bind('<Button-1>', self.eventManager) # 点击按钮事件
self.btn_quit.bind('<Button-1>', self.eventManager) # 点击按钮事件
self.master.bind('<KeyPress-r>', self.hotKey) # 绑定快捷键
self.master.bind('<KeyPress-g>', self.hotKey) # 绑定快捷键
self.master.bind('<KeyPress-b>', self.hotKey) # 绑定快捷键
self.master.bind('<KeyPress-y>', self.hotKey) # 绑定快捷键
self.master.bind('<KeyPress-q>', self.hotKey) # 绑定快捷键
self.drawpad.bind('<ButtonRelease-1>', self.stopDraw) # 左键释放按钮

def eventManager(self, event):
name = event.widget.winfo_name()
print(name)
self.start_flag = True
if name == 'line':
# 左键拖动
self.drawpad.bind('<B1-Motion>', self.myline)
elif name == 'line_arrow':
self.drawpad.bind('<B1-Motion>', self.myline_arrow)
elif name == 'rect':
self.drawpad.bind('<B1-Motion>', self.myrect)
elif name == 'pen':
self.drawpad.bind('<B1-Motion>', self.mypen)
elif name == 'erasor':
self.drawpad.bind('<B1-Motion>', self.myerasor)
elif name == 'clear':
self.drawpad.delete('all')
elif name == 'color':
c = askcolor(color=self.fgcolor, title='请选择颜色')
print(c) # c的值 ((128.5, 255.99609375, 0.0), '#80ff00')
self.fgcolor = c[1]
elif name == 'quit':
quit()

def startDraw(self, event):
self.drawpad.delete(self.lastdraw)
if self.start_flag:
self.start_flag = False
self.x = event.x
self.y = event.y

def stopDraw(self, event):
self.start_flag = True
self.lastdraw = 0

def myline(self, event):
self.startDraw(event)
self.lastdraw = self.drawpad.create_line(self.x, self.y, event.x, event.y, fill=self.fgcolor)

def myline_arrow(self, event):
self.startDraw(event)
self.lastdraw = self.drawpad.create_line(self.x, self.y, event.x, event.y, arrow=LAST, fill=self.fgcolor)

def myrect(self, event):
self.startDraw(event)
self.lastdraw = self.drawpad.create_rectangle(self.x, self.y, event.x, event.y, outline=self.fgcolor)

def mypen(self, event):
self.startDraw(event)
print('self.x=', self.x, ',self.y=', self.y)
self.drawpad.create_line(self.x, self.y, event.x, event.y, fill=self.fgcolor)
self.x = event.x
self.y = event.y

def myerasor(self, event):
self.startDraw(event)
print('self.x=', self.x, ',self.y=', self.y)
self.drawpad.create_line(self.x, self.y, event.x, event.y, fill='white')
self.x = event.x
self.y = event.y

def hotKey(self, event):
c = event.char
if c == 'r':
self.fgcolor = 'red'
elif c == 'g':
self.fgcolor = 'green'
elif c == 'b':
self.fgcolor = 'blue'
elif c == 'y':
self.fgcolor = 'yellow'

class SketchFrame(wx.Frame):

def __init__(self):
super().__init__(parent=None, id=-1,
title="白板",
size=(800,600)
)


self.sketch = SketchWindow(parent=self, id=-1)

# 窗口居中
self.Center()


Loading

0 comments on commit d06c8a9

Please sign in to comment.