【Python程序设计】GUI 编程

Alex_Shen
2022-03-31 / 0 评论 / 0 点赞 / 111 阅读 / 14,091 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-04-06,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1. 编写 GUI 程序,如图所示,显示 10 个随机颜色的球并放置在随机位置,按Display键更新球颜色和位置。

image-20220331021955079

思路:

  1. 构建GUI程序界面
window = Tk()

window.title("Problem1")

frame = Frame(window)

frame.pack()

self.canvas = Canvas(frame, **width**=400, **height**=200, **bg**='white')

self.canvas.pack()

display_button = Button(frame, **text**='Display', **command**=**self**.reset)

display_button.pack()

window.mainloop()

img

  1. 编写生成函数

(1) 首先删除画布上面的所有元素(以防与下一次生成的点同时出现)

self.canvas.delete("all")

(2) 随机生成10个点,其中x,y,r均随机。并且生成图形

    for i in range(0, 10):
      x, y = random.randint(0, 400), random.randint(0, 200)
      r = random.randint(5, 10)
      self.canvas.create_oval(x-r, y-r, x+r, y+r,
                  fill=****self****.rand_color())

(3) 其中的颜色随机,是通过生成随机16进制颜色来实现的。

  def rand_color(self):

    colorArr = ['1', '2', '3', '4', '5', '6', '7',
          '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
    color = ""
    for i in range(6):
       color += colorArr[random.randint(0, 14)]
    return "#"+color

img

from tkinter import *
import random

class Demo:
    def __init__(self) -> None:
        window = Tk()
        window.title("Problem1")
        frame = Frame(window)
        frame.pack()

        self.canvas = Canvas(frame, width=400, height=200, bg='white')
        self.canvas.pack()

        display_button = Button(frame, text='Display', command=self.reset)
        display_button.pack()

        window.mainloop()

    def reset(self):
        self.canvas.delete("all")
        for i in range(0, 10):
            x, y = random.randint(0, 400), random.randint(0, 200)
            r = random.randint(5, 10)
            self.canvas.create_oval(x-r, y-r, x+r, y+r,
                                    fill=self.rand_color())

    def rand_color(self):
        colorArr = ['1', '2', '3', '4', '5', '6', '7',
                    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
        color = ""
        for i in range(6):
            color += colorArr[random.randint(0, 14)]
        return "#"+color

Demo()

2. 编写 GUI 程序,求解二元一次线性方程组,自行设计 GUI 界面,允许用户在输入框中输入参数 a、b、c、d、e、f,并输出方程组的解。

思路:

  1. 构建GUI程序界面

            window = Tk()
            window.title("Problem1")
            frame = Frame(window)
            frame.pack()
    
            self.a = StringVar()
            self.b = StringVar()
            self.c = StringVar()
            self.d = StringVar()
            self.e = StringVar()
            self.f = StringVar()
    
            Entry(frame, textvariable=self.a).grid(row=1, column=1)
            Label(frame, text="x + ").grid(row=1, column=2)
            Entry(frame, textvariable=self.b,).grid(row=1, column=3)
            Label(frame, text="y = ").grid(row=1, column=4)
            Entry(frame, textvariable=self.e).grid(row=1, column=5)
    
            Entry(frame, textvariable=self.c).grid(row=2, column=1)
            Label(frame, text="x + ").grid(row=2, column=2)
            Entry(frame, textvariable=self.d).grid(row=2, column=3)
            Label(frame, text="y = ").grid(row=2, column=4)
            Entry(frame, textvariable=self.f).grid(row=2, column=5)
            Button(frame, text='计算, command=self.cal).grid(row=3, column=3)
    
  2. 获取系数信息,并且判断输入合法性

        a = self.a.get()
        b = self.b.get()
        c = self.c.get()
        d = self.d.get()
        e = self.e.get()
        f = self.f.get()
        if a.isdigit() and b.isdigit() and c.isdigit() and d.isdigit() and e.isdigit() and f.isdigit():
            Xxxxxx
        else:
            tkinter.messagebox.showinfo(
                "求解二元一次方程", "非法输入")
  1. 调用np.linalg.solve,解二元一次方程,并展示解的信息

    if a.isdigit() and b.isdigit() and c.isdigit() and d.isdigit() and e.isdigit() and f.isdigit():
    
    x = np.linalg.solve(
                    [[int(a), int(b)], [int(c), int(d)]], [int(e), int(f)])
          
    tkinter.messagebox.showinfo("求解二元一次方程”, "x = {:.2f}, y = {:.2f}".format(x[0], x[1]))
    

    img

    img

from tkinter import *
import tkinter.messagebox
import numpy as np


class Demo:
    def __init__(self) -> None:
        window = Tk()
        window.title("Problem1")
        frame = Frame(window)
        frame.pack()

        self.a = StringVar()
        self.b = StringVar()
        self.c = StringVar()
        self.d = StringVar()
        self.e = StringVar()
        self.f = StringVar()

        Entry(frame, textvariable=self.a).grid(row=1, column=1)
        Label(frame, text="x + ").grid(row=1, column=2)
        Entry(frame, textvariable=self.b,).grid(row=1, column=3)
        Label(frame, text="y = ").grid(row=1, column=4)
        Entry(frame, textvariable=self.e).grid(row=1, column=5)

        Entry(frame, textvariable=self.c).grid(row=2, column=1)
        Label(frame, text="x + ").grid(row=2, column=2)
        Entry(frame, textvariable=self.d).grid(row=2, column=3)
        Label(frame, text="y = ").grid(row=2, column=4)
        Entry(frame, textvariable=self.f).grid(row=2, column=5)

        Button(frame, text='计算', command=self.cal).grid(row=3, column=3)

        window.mainloop()

    def cal(self):
        a = self.a.get()
        b = self.b.get()
        c = self.c.get()
        d = self.d.get()
        e = self.e.get()
        f = self.f.get()
        if a.isdigit() and b.isdigit() and c.isdigit() and d.isdigit() and e.isdigit() and f.isdigit():
            x = np.linalg.solve(
                [[int(a), int(b)], [int(c), int(d)]], [int(e), int(f)])
            tkinter.messagebox.showinfo(
                "求解二元一次方程", "x = {:.2f}, y = {:.2f}".format(x[0], x[1]))
        else:
            tkinter.messagebox.showinfo(
                "求解二元一次方程", "非法输入")


Demo()

3. 编写 GUI 程序,如图所示,显示两个半径为 20 的圆,并用一条线连接这两个圆的圆心。

要求:

(1) 两圆心之间的距离在线上显示。

(2) 允许用户拖动任何一个圆时,圆和直线跟随移动,两圆之间的距离更新。

(3) 要求两圆不能重叠。

思路:

  1. 构建GUI程序界面,其中初始化随机生成两个圆并连线,文字信息出现在连线中点。
        window = Tk()
        window.title("Problem1")
        frame = Frame(window)
        frame.pack()

        self.canvas = Canvas(frame, width=400, height=200, bg='white')
        self.canvas.pack()

        self.x1,self.x2 = random.randint(0, 400), random.randint(0, 400)
        self.y1,self.y2 = random.randint(0, 200), random.randint(0, 200)
        self.r = 20

        self.canvas.create_oval(
            self.x1-self.r, self.y1-self.r,
            self.x1+self.r, self.y1+self.r,
            fill='red', tag='circle1',)
        self.canvas.create_oval(
            self.x2-self.r, self.y2-self.r,
            self.x2+self.r, self.y2+self.r,
            fill='red', tags='circle2')
        self.canvas.create_line(self.x1, self.y1,
                                self.x2, self.y2,
                                tags='line')
        self.canvas.create_text((self.x1+self.x2)/2, (self.y1+self.y2)/2,text="{:.2f}".format(self.get_dis()), tags='dis')
  1. 绑定按键信息
        self.canvas.bind("<B1-Motion>", self.MouseEvent)

并且判断正在点击哪一个圆(根据点击位置与圆心位置判断)

   def MouseEvent(self, event):
        cur_x, cur_y = event.x, event.y
        if cur_x > self.x1-self.r and cur_x < self.x1+self.r and cur_y > self.y1-self.r and cur_y < self.y1+self.r:
            Xxxxxxxxxxx
        
        elif cur_x > self.x2-self.r and cur_x < self.x2+self.r and cur_y > self.y2-self.r and cur_y < self.y2+self.r:
            Xxxxxxxxxxx
  1. 更新画板信息:删除原来的图形,并根据点击位置生成新图形。
            self.x2 = cur_x
            self.y2 = cur_y

            self.canvas.delete('circle2')
            self.canvas.create_oval(
                self.x2-self.r, self.y2-self.r,
                self.x2+self.r, self.y2+self.r,
                fill='red', tag='circle2',)

            self.canvas.delete('line')
            self.canvas.create_line(self.x1, self.y1,
                                    self.x2, self.y2,
                                    tags='line')

            self.canvas.delete('dis')
            self.canvas.create_text((self.x1+self.x2)/2, (self.y1+self.y2)/2,text="{:.2f}".format(self.get_dis()), tags='dis')
  1. 判断是否重叠,如果重叠弹出警告
            if(cur_x == self.x1 and cur_y == self.y1):
                tkinter.messagebox.showinfo(
                    "Problem 3", "禁止重叠")

img

img

import math
from tkinter import *
import random
import tkinter.messagebox


class Demo:
    def __init__(self) -> None:
        window = Tk()
        window.title("Problem1")
        frame = Frame(window)
        frame.pack()

        self.canvas = Canvas(frame, width=400, height=200, bg='white')
        self.canvas.pack()

        self.x1, self.x2 = random.randint(0, 400), random.randint(0, 400)
        self.y1, self.y2 = random.randint(0, 200), random.randint(0, 200)
        self.r = 20

        self.canvas.create_oval(
            self.x1-self.r, self.y1-self.r,
            self.x1+self.r, self.y1+self.r,
            fill='red', tag='circle1',)

        self.canvas.create_oval(
            self.x2-self.r, self.y2-self.r,
            self.x2+self.r, self.y2+self.r,
            fill='red', tags='circle2')

        self.canvas.create_line(self.x1, self.y1,
                                self.x2, self.y2,
                                tags='line')

        self.canvas.create_text((self.x1+self.x2)/2, (self.y1+self.y2)/2,
                                text="{:.2f}".format(self.get_dis()), tags='dis')

        self.canvas.bind("<B1-Motion>", self.MouseEvent)

        window.mainloop()

    def get_dis(self):
        return math.sqrt((self.x1-self.x2)**2+(self.y1-self.y2)**2)

    def MouseEvent(self, event):
        cur_x, cur_y = event.x, event.y
        if cur_x > self.x1-self.r and cur_x < self.x1+self.r and cur_y > self.y1-self.r and cur_y < self.y1+self.r:
            if(cur_x==self.x2 and cur_y == self.y2):
                tkinter.messagebox.showinfo(
                    "Problem 3", "禁止重叠")
                return
            self.x1 = cur_x
            self.y1 = cur_y
            self.canvas.delete('circle1')
            self.canvas.create_oval(
                self.x1-self.r, self.y1-self.r,
                self.x1+self.r, self.y1+self.r,
                fill='red', tag='circle1',)

            self.canvas.delete('line')
            self.canvas.create_line(self.x1, self.y1,
                                    self.x2, self.y2,
                                    tags='line')

            self.canvas.delete('dis')
            self.canvas.create_text((self.x1+self.x2)/2, (self.y1+self.y2)/2,
                                    text="{:.2f}".format(self.get_dis()),tags='dis')
        
        elif cur_x > self.x2-self.r and cur_x < self.x2+self.r and cur_y > self.y2-self.r and cur_y < self.y2+self.r:
            if(cur_x == self.x1 and cur_y == self.y1):
                tkinter.messagebox.showinfo(
                    "Problem 3", "禁止重叠")
                return
            self.x2 = cur_x
            self.y2 = cur_y
            self.canvas.delete('circle2')
            self.canvas.create_oval(
                self.x2-self.r, self.y2-self.r,
                self.x2+self.r, self.y2+self.r,
                fill='red', tag='circle2',)

            self.canvas.delete('line')
            self.canvas.create_line(self.x1, self.y1,
                                    self.x2, self.y2,
                                    tags='line')

            self.canvas.delete('dis')
            self.canvas.create_text((self.x1+self.x2)/2, (self.y1+self.y2)/2,
                                    text="{:.2f}".format(self.get_dis()), tags='dis')


Demo()

4. 编写 GUI 程序,如图所示,用户单击 Browse 按钮打开一个文件对话框,然后选择一个文件,选择的文件显示在输入字段中。单击 ShowResult 按钮计算和显示文件中每个字母的出现次数。

image-20220331023115357

思路:

  1. 构建GUI程序界面
        window = Tk()
        frame1 = Frame(window)
        frame1.pack()
        frame2 = Frame(window)
        frame2.pack()
        scrollbar = Scrollbar(frame1)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.text = Text(frame1, width=50, height=20, wrap=WORD,
                         yscrollcommand=scrollbar.set)
        self.text.configure(state='disabled')
        self.text.pack()

        scrollbar.config(command=self.text.yview)

        self.label1 = Label(
            frame2, text='Enter a file name:').grid(row=1, column=1)
        self.path = Label(frame2, height=1)
        self.path.grid(row=1, column=2)
        self.browse = Button(frame2, text='Browse',command=self.choose_file).grid(row=1, column=3)
        self.show_result = Button(frame2, text='Show Result', command=self.show).grid(row=1, column=4)
  1. 绑定按钮
        self.browse = Button(frame2, text='Browse',command=self.choose_file).grid(row=1, column=3)

利用tkinter.filedialog 中的 askopenfilename 对象,选择文件。

其中参数的含义是可选择的文件类型,以及默认打开路径

        self.file_path = askopenfilename(title='Select the .exe / .py file', filetypes=[、('Python', '*.py'), ('Txt', '*.txt')], initialdir='I:\\大二下\\Python程序设计')

在文本框中展示文件路径

        self.path.configure(text=self.file_path)
  1. 绑定按钮
        self.show_result = Button(frame2, text='Show Result', command=self.show).grid(row=1, column=4)

设置字母字典

        dic = {i: 0 for i in string.ascii_lowercase}

设置警告信息

        if self.file_path == "":
            tkinter.messagebox.showwarning('警告!', "当前路径下无文件。")

打开文件并统计字母个数

            f = open(self.file_path, mode='r')
            while True:
                line = f.readline()
                if not line:
                    break
                line = line.lower()
                for ch in line:
                    if ch in dic:
                        dic[ch] += 1

展示信息,先将文本框清空,状态改为normal(可修改),并在文本框中展示信息,最后状态改为disabled(不可修改)

        self.text.configure(state='normal')
        self.text.delete('1.0', 'end')
        for i in dic:
            self.text.insert(END, "{} appear {} times\n".format(i, dic[i]))
        self.text.configure(state='disabled')

img

from os import stat
from tkinter import *
from tkinter.filedialog import askopenfilename
import tkinter.messagebox
import numpy as np
import string


class Demo:
    def __init__(self) -> None:
        window = Tk()
        frame1 = Frame(window)
        frame1.pack()
        frame2 = Frame(window)
        frame2.pack()
        scrollbar = Scrollbar(frame1)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.text = Text(frame1, width=50, height=20, wrap=WORD,
                         yscrollcommand=scrollbar.set)
        self.text.configure(state='disabled')
        self.text.pack()

        scrollbar.config(command=self.text.yview)

        self.label1 = Label(
            frame2, text='Enter a file name:').grid(row=1, column=1)
        self.path = Label(frame2, height=1)
        self.path.grid(row=1, column=2)
        self.browse = Button(frame2, text='Browse',
                             command=self.choose_file).grid(row=1, column=3)
        self.show_result = Button(
            frame2, text='Show Result', command=self.show).grid(row=1, column=4)

        self.file_path = ''
        window.mainloop()

    def choose_file(self):
        self.file_path = askopenfilename(title='Select the .txt / .py file', filetypes=[
            ('Python', '*.py'), ('Txt', '*.txt')], initialdir='I:\\大二下\\Python程序设计')
        self.path.configure(text=self.file_path)

    def show(self):
        dic = {i: 0 for i in string.ascii_lowercase}
        if self.file_path == "":
            tkinter.messagebox.showwarning('警告!', "当前路径下无文件。")
            return
        else:
            f = open(self.file_path, mode='r')
            while True:
                line = f.readline()
                if not line:
                    break
                line = line.lower()
                for ch in line:
                    if ch in dic:
                        dic[ch] += 1
        self.text.configure(state='normal')
        self.text.delete('1.0', 'end')
        for i in dic:
            self.text.insert(END, "{} appear {} times\n".format(i, dic[i]))
        self.text.configure(state='disabled')


Demo()

0

评论区