欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python程序设计之GUI(9)

程序员文章站 2022-03-02 13:28:36
...
1.创建画布

①画布初始化

import tkinter
import tkinter.simpledialog
import tkinter.filedialog
import tkinter.colorchooser
app = tkinter.Tk()
app.title('My Paint')
app['width'] = 800
app['height'] = 600

#控制是否允许画图的变量,1:允许,0:不允许
yesno = tkinter.IntVar(value=0)
#控制画图类型的变量,1:曲线,2:直线,3:矩形,4:文本,5:橡皮
what = tkinter.IntVar(value=1)
#记录鼠标位置的变量
X = tkinter.IntVar(value=0)
Y = tkinter.IntVar(value=0)
#前景色
foreColor = '#000000'
backColor = '#FFFFFF'

#创建画布
image = tkinter.PhotoImage()
canvas = tkinter.Canvas(app, bg=foreColor,width=800, height=600)
canvas.create_image(800, 600, image=image)

②添加操作

#鼠标左键单击,允许画图
def onLeftButtonDown(event):
    yesno.set(1)
    X.set(event.x)
    Y.set(event.y)
    if what.get()==4:
        canvas.create_text(event.x, event.y, text=text)
canvas.bind('<Button-1>', onLeftButtonDown)

#记录最后绘制图形的id
lastDraw = 0

#按住鼠标左键移动,画图
def onLeftButtonMove(event):
    global lastDraw
    if yesno.get()==0:
        return
    if what.get()==1:
        #使用当前选择的前景色绘制曲线
        canvas.create_line(X.get(), Y.get(), event.x, event.y, fill=foreColor)
        X.set(event.x)
        Y.set(event.y)
    elif what.get()==2:
        #绘制直线,先删除刚刚画过的直线,再画一条新的直线
        #global lastDraw
        try:
            canvas.delete(lastDraw)
        except Exception as e:
            pass
        lastDraw = canvas.create_line(X.get(), Y.get(), event.x, event.y,
                                      fill=foreColor)
    elif what.get()==3:
        #绘制矩形,先删除刚刚画过的矩形,再画一个新的矩形
        #global lastDraw
        try:
            canvas.delete(lastDraw)
        except Exception as e:
            pass
        lastDraw = canvas.create_rectangle(X.get(), Y.get(), event.x, event.y,
                                           fill=backColor, outline=foreColor)
    elif what.get()==5:
        #橡皮,使用背景色填充10*10的矩形区域
        canvas.create_rectangle(event.x-5, event.y-5, event.x+5, event.y+5,
                                outline=backColor, fill=backColor)
canvas.bind('<B1-Motion>', onLeftButtonMove)
#鼠标左键抬起,不允许画图
def onLeftButtonUp(event):
    if what.get()==2:
        #绘制直线
        canvas.create_line(X.get(), Y.get(), event.x, event.y, fill=foreColor)
    elif what.get()==3:
        #绘制矩形
        canvas.create_rectangle(X.get(), Y.get(), event.x, event.y,fill=backColor, outline=foreColor)
    yesno.set(0)
    global lastDraw
    lastDraw = 0
canvas.bind('<ButtonRelease-1>', onLeftButtonUp)

#创建菜单
menu = tkinter.Menu(app, tearoff=0)
#打开图像文件
def Open():
    filename = tkinter.filedialog.askopenfilename(title='Open Image',filetypes=[('image', '*.jpg *.png *.gif')])
    if filename:
        global image
        image = tkinter.PhotoImage(file=filename)
        canvas.create_image(80, 80, image=image)
menu.add_command(label='Open', command=Open)

#添加菜单,清除
def Clear():
    for item in canvas.find_all():
        canvas.delete(item)
menu.add_command(label='Clear', command=Clear)

#添加分割线
menu.add_separator()

#创建子菜单,用来选择绘图类型
menuType = tkinter.Menu(menu, tearoff=0)
def drawCurve():
    what.set(1)
    print(what.get())
menuType.add_command(label='Curve', command=drawCurve)

def drawLine():
    what.set(2)
menuType.add_command(label='Line', command=drawLine)

def drawRectangle():
    what.set(3)
menuType.add_command(label='Rectangle', command=drawRectangle)

def drawText():
    global text
    text = tkinter.simpledialog.askstring(title='Input what you want to draw',prompt='')
    what.set(4)
menuType.add_command(label='Text', command=drawText)
menuType.add_separator()

#选择前景色
def chooseForeColor():
    global foreColor
    foreColor = tkinter.colorchooser.askcolor()[1]
menuType.add_command(label='Choose Foreground Color', command=chooseForeColor)

#选择背景色
def chooseBackColor():
    global backColor
    backColor = tkinter.colorchooser.askcolor()[1]

menuType.add_command(label='Choose Background Color', command=chooseBackColor)

#橡皮
def onErase():
    what.set(5)
menuType.add_command(label='Erase', command=onErase)
menu.add_cascade(label='Type', menu=menuType)

#鼠标右键抬起,弹出菜单
def onRightButtonUp(event):
    menu.post(event.x_root, event.y_root)
canvas.bind('<ButtonRelease-3>', onRightButtonUp)
canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES)

2.电子时钟

①闹钟初始化

import tkinter
import threading
import datetime
import time

app = tkinter.Tk()
app.overrideredirect(True)            #不显示标题栏
app.attributes('-alpha', 0.9)         #半透明
app.attributes('-topmost', 1)         #总是在顶端
app.geometry('110x25+100+100')        #初始大小与位置
labelDateTime = tkinter.Label(app)
labelDateTime.pack(fill=tkinter.BOTH, expand=tkinter.YES)
labelDateTime.configure(bg = 'gray')

X = tkinter.IntVar(value=0)           #记录鼠标左键按下的位置
Y = tkinter.IntVar(value=0)
canMove = tkinter.IntVar(value=0)     #窗口是否可拖动
still = tkinter.IntVar(value=1)       #是否仍在运行

def onLeftButtonDown(event):
    app.attributes('-alpha', 0.4)     #开始拖动时增加透明度
    X.set(event.x)                    #鼠标左键按下,记录当前位置
    Y.set(event.y)
    canMove.set(1)                    #并标记窗口可拖动
labelDateTime.bind('<Button-1>', onLeftButtonDown)

def onLeftButtonUp(event):
    app.attributes('-alpha', 0.9)     #停止拖动时恢复透明度
    canMove.set(0)                    #鼠标左键抬起,标记窗口不可拖动
labelDateTime.bind('<ButtonRelease-1>', onLeftButtonUp)

def onLeftButtonMove(event):
    if canMove.get()==0:
        return
    newX = app.winfo_x()+(event.x-X.get())
    newY = app.winfo_y()+(event.y-Y.get())
    g = '110x25+'+str(newX)+'+'+str(newY)
    app.geometry(g)                   #修改窗口的位置
labelDateTime.bind('<B1-Motion>', onLeftButtonMove)

def onRightButtonDown(event):
    still.set(0)
    t.join(0.2)
    app.destroy()                     #关闭窗口
labelDateTime.bind('<Button-3>', onRightButtonDown)

def nowDateTime():
    while still.get()==1:
        now = datetime.datetime.now()
        s = str(now.year)+'-'+str(now.month)+'-'+str(now.day)+' '
        s = s+str(now.hour)+':'+str(now.minute)+':'+str(now.second)
        labelDateTime['text'] = s     #显示当前时间
        time.sleep(0.2)
t = threading.Thread(target=nowDateTime)
t.daemon = True
t.start()