diff --git a/homepage.py b/homepage.py index 6d978e1..8e3339b 100644 --- a/homepage.py +++ b/homepage.py @@ -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): @@ -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) diff --git a/paint.py b/paint.py index 4df4b11..440699d 100644 --- a/paint.py +++ b/paint.py @@ -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() diff --git a/physics.py b/physics.py new file mode 100644 index 0000000..2fb9baa --- /dev/null +++ b/physics.py @@ -0,0 +1,38 @@ +from ursina import * +from ursina.prefabs.first_person_controller import FirstPersonController +from ursina.prefabs.sky import Sky +from ursina.shaders import lit_with_shadows_shader + +app = Ursina() + +plane = Entity(model="cube", texture="img/grass.png", scale=(100, 1, 100), position=(0, 0, 0), collider='box', shader=lit_with_shadows_shader) + +car1 = Entity(model="model/blue_car.obj", texture="model/blue_car.mtl", scale=(0.2, 0.1, 0.1), position=(-10, 0.6, 0), collider='box', shader=lit_with_shadows_shader) +# desk = Entity(model="cube", texture="white_cube", scale=(8, 1, 1.5), position=(0, 1, 0), collider='box', shader=lit_with_shadows_shader) +wenzi1 = Entity(model="model/wenzi1.obj", scale=(1, 1, 1), position=(-10, 6, 0), rotation_x=90, rotation_y=180, shader=lit_with_shadows_shader) + +car2 = Entity(model="model/blue_car.obj", texture="model/blue_car.mtl", scale=(0.2, 0.1, 0.1), position=(-10, 0.6, 22), collider='box', shader=lit_with_shadows_shader) +car3 = Entity(model="model/red_car.obj", texture="model/red_car.mtl", scale=(0.2, 0.1, 0.1), position=(-10, 0.6, 20), collider='box', shader=lit_with_shadows_shader) +wenzi2 = Entity(model="model/wenzi2.obj", scale=(1, 1, 1), position=(-10, 10, 20), rotation_x=90, rotation_y=180, shader=lit_with_shadows_shader) + +water = Entity(model="cube", texture="img/water.png", scale=(2, 1, 2), position=(-10, 1, 30), shader=lit_with_shadows_shader) +water_block = Entity(model="cube", texture="white_cube", scale=(0.5, 0.5, 0.5), position=(-10, 1, 30), shader=lit_with_shadows_shader) +water_block = Entity(model="cube", texture="white_cube", scale=(0.5, 0.5, 0.5), position=(-10, 2.2, 30), shader=lit_with_shadows_shader, collider='box') +wenzi3 = Entity(model="model/wenzi3.obj", scale=(1, 1, 1), position=(-10, 8, 30), rotation_x=90, rotation_y=180, shader=lit_with_shadows_shader) + +car1.animate_x(0, duration=3, loop=True) +car2.animate_x(1, duration=5, loop=True) +car3.animate_x(3, duration=3, loop=True) + +Text.default_font = 'font/DroidSansFallback.ttf' + + +pivot = Entity() +DirectionalLight(parent=pivot, x=1000, y=100, z=-10, shadows=True) + +# player = EditorCamera() +player = FirstPersonController(speed=20, position=(0,2,-10)) +camera.overlay = None + +sky = Sky() +app.run()