Pythonの小さな演習-GUIデザイン

演習1:キャンバスの使用

直線、円、半円、三角形、その他の画像を描画したり、画像を挿入したりするためのテスト


from tkinter import *
from tkinter import messagebox

#定义坐标位置
lineposition = ((30,50),(300,100),(20,50))
rectposition = ((50,50),(100,100))
ovalposition = ((150,50),(250,150))
arcposition = ((350,50),(250,150))
coorposition = ((100,100),(50,150),(150,150),(80,200),(120,200))

class Application(Frame):

    def __init__(self,master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.TestCanvas()

    def TestCanvas(self):
        canvas = Canvas(self, width = 500, height = 350)
        canvas["bg"] = "blue"
        canvas.pack()
		
		#画直线
        line = canvas.create_line(lineposition)
        #画矩形
        rect = canvas.create_rectangle(rectposition)
        #画圆形
        oval = canvas.create_oval(ovalposition)
        #画四分一圆形
        arc = canvas.create_arc(arcposition)
        #画多边形
        coor1 = canvas.create_polygon(coorposition)
        coor2 = canvas.create_polygon(200,200,400,200,300,300)
		
		#插入图画
        global photo
        photo = PhotoImage(file="photo/pngphoto/小黄人.png")
        canvas.create_image(380,250,image=photo)

Clichong = Tk()
Clichong.geometry("600x400+100+200")
Clichong.title("GUI设计测试")
app = Application(master=Clichong)
app.mainloop()

ここに画像の説明を挿入
ここに画像の説明を挿入

演習2:3つのレイアウトマネージャーを練習する

tkinterは、pack、grid、placeの3種類のマネージャーを提供します。

1.グリッドレイアウトマネージャー

グリッドテーブルレイアウト。テーブル構造を使用してコンポーネントを整理します。サブコンポーネントの位置は行と列のセルによって決定され、行と列にまたがって複雑なレイアウトを実現できます。
ここに画像の説明を挿入
テスト1:簡単なログインインターフェイスを作成する

#使用grid布局

from tkinter import *
from tkinter import messagebox

class Application(Frame):

    def __init__(self,master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.Mytest()

    def Mytest(self):

        lb1 = Label(self,text="用户名:")
        lb1.grid(row=0,column=0)

        et1 = Entry(self,show="*")
        et1.grid(row=0,column=1)

        bt1 = Button(self,width=5,height=1,text="登录")
        bt1.grid(row=1,column=1,sticky="es")    # sticky控制好方位

Clichong = Tk()
Clichong.geometry("600x400+100+200")
Clichong.title("GUI设计测试")
app = Application(master=Clichong)
app.mainloop()

ここに画像の説明を挿入
テスト2:電卓の簡単なレイアウトを書く

#使用grid布局

from tkinter import *
from tkinter import messagebox

#定义好按钮上面text内容
btnumber = (("MC","M+","M-","MR"),\
            ("C","±","+","*"),\
            (7,8,9,"-"),\
            (4,5,6,"+"),\
            (1,2,3,"="),\
            (0,"."))

class Application(Frame):

    def __init__(self,master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.Mytest()

    def Mytest(self):

        Entry(self).grid(row=0,column=0,columnspan=4,pady=10,sticky="nsew")

        print((list(enumerate(btnumber))))
        for rows,datainfo in enumerate(btnumber):
            for nums,singledatainfo in enumerate(datainfo):
                #对于等号与点号需要做特殊在处理
                if singledatainfo == "=":
                    Button(self,text=singledatainfo).grid(row=rows+1,column=nums,rowspan=2,sticky="nsew")
                elif singledatainfo == ".":
                    Button(self, text=singledatainfo).grid(row=rows + 1, column=nums, columnspan=2, sticky="nsew")
                else:
                    Button(self,text=singledatainfo).grid(row=rows+1,column=nums,sticky="nsew")


Clichong = Tk()
Clichong.geometry("140x220+100+200")
Clichong.title("GUI设计测试")
app = Application(master=Clichong)
app.mainloop()

ここに画像の説明を挿入

2.パックレイアウトマネージャー

Packは、コンポーネントの作成順に子コンポーネントを親コンポーネントに追加し、それらを垂直方向または水平方向に自然に配置します。オプションを指定しない場合、デフォルトでは、親コンポーネントにコンポーネントを上から下に垂直に追加します。
ここに画像の説明を挿入
テスト:ピアノのキーレイアウトを作成する

#使用grid布局

from tkinter import *
from tkinter import messagebox

btstring = ("伴奏1","伴奏2","伴奏3","旋律1","旋律2")

Clichong = Tk()
Clichong.geometry("500x240+300+300")
Clichong.title("钢琴键")

# 思路,这里我们需要定义两个pack,一个放按钮,另外一个放置钢琴键。而这两个pack都在Clichong这个背景上面
# 放置按钮
pianobt = Frame(Clichong)
pianobt.pack(pady=15)
for bttext in btstring:
    Button(pianobt,text=bttext,width=5,height=1).pack(side="left",padx=10)

# 放置钢琴键
pianoky = Frame(Clichong)
pianoky.pack(pady=10)
for btpiano in range(0,11):
    Button(pianoky,width=5,height=10,bg="black" if btpiano%2==0 else "white").pack(side="left")

# 一定要设置循环,不然无法实现
Clichong.mainloop()

ここに画像の説明を挿入

3.レイアウトマネージャーを配置します

場所レイアウトマネージャーは、座標を介してコンポーネントの位置を正確に制御できます。これは、より柔軟なレイアウトを使用する一部のシナリオに適しています。
ここに画像の説明を挿入
ここに画像の説明を挿入
テスト1:プレイスコンポーネントをテストするだけです

# 测试place布局
from tkinter import *

Clichong = Tk()
Clichong.geometry("400x200+400+300")
Clichong["bg"] = "blue"

# 放置一个黄色的方框
fm1 = Frame(Clichong,bg="yellow",width=100,height=100)
fm1.place(x=30,y=35)

# 放置一个绿色的方框
fm2 = Frame(Clichong,bg="green",width=100,height=100)
fm2.place(x=270,y=35)

# 放置三个按钮
Button(fm1,text="bt1",bg="green").place(relx=0.3,rely=0.7)
Button(fm2,text="bt2",bg="yellow").place(relx=0.7,rely=0.3)
Button(Clichong,text="bt",bg="white").place(width=60,height=30,relx=0.45,rely=0.4)

Clichong.mainloop()

ここに画像の説明を挿入
テスト2:トランプゲームの操作設定

# 扑克出牌

from tkinter import *

Clichong = Tk()
Clichong.geometry("600x400+300+300")

# 图像处理
myphoto = [PhotoImage(file="photo/puke/puke"+str(pukenumber+1)+".gif")for pukenumber in range(10)]
mypuke = [Label(Clichong,image=myphoto[i])for i in range(10)]

# 放置扑克牌
for i in range(10):
    mypuke[i].place(x=50+40*i,y=130)

# 触发事件的操作函数
def pukeoutfunction(event):
    print(event.widget.winfo_geometry())    # 打印geometry信息
    print(event.widget.winfo_y())           # 打印y坐标
    # 如果y坐标在底下,则出牌
    if event.widget.winfo_y() == 130:
        event.widget.place(y=80)
    # 如果y坐标已出,则收牌
    else:
        event.widget.place(y=130)

# 对label事件点击的绑定出牌操作
mypuke[1].bind_class("Label","<Button-1>",pukeoutfunction)

Clichong.mainloop()

初期状態
ここに画像の説明を挿入
任意のカードを
ここに画像の説明を挿入
クリックしもう一度クリックして元に戻します
ここに画像の説明を挿入

演習3:マウスイベントとキーボードイベントの使用法

  GUIアプリケーションのライフサイクル全体がイベントループにあります。イベントの発生を待ち、それに応じて処理します。Tkinterは、関連するイベントを処理するメカニズムを提供します。ハンドル関数は、各コントロールのさまざまなイベントにバインドできます。widget.bind(event、handler)関連するイベントが発生すると、ハンドラー関数がトリガーされ、イベントオブジェクトイベントがハンドラー関数に渡されます。

マウスとキーボードのイベント:
ここに画像の説明を挿入
イベントオブジェクトの一般的な属性:
ここに画像の説明を挿入


from tkinter import *

Clichong = Tk()
Clichong.geometry("600x400+300+300")

bt1 = Button(Clichong,bg="blue",text="bt1").place(x=50,y=120,width=50,height=20)
#lb1 = Label(Clichong,bg="pink").place(x=300,y=100,width=100,height=30)

c1 = Canvas(Clichong,width=50,height=50,bg="pink")
c1.place(x=50,y=20)
c2 = Canvas(Clichong,width=200,height=200,bg="orange")
c2.place(x=120,y=20)

# 打印相关信息,测试event 对象常用属性
def mouseTest(event):
    print("鼠标左键单击位置(相对于父容器):{0},{1}".format(event.x,event.y))
    print("鼠标左键单击位置(相对于屏幕):{0},{1}".format(event.x_root,event.y_root))
    print("事件绑定的组件:{0}".format(event.widget))
    print("event.type:{0}".format(event.type))
    print("event.width:{0},event.height:{1}".format(event.width,event.height))

penfont=2         # 设置画笔的粗细
def mouseDrag(event):
    # 不断的画圆,看上去像是画笔,但是event.x+var加大了就知道是个圆
    c2.create_oval(event.x, event.y, event.x+penfont, event.y+penfont)

# 键盘任意按键触发事件,打印按下的键盘键,测试event 对象常用属性
def keyboardTest(event):
    print("按键keycode:{0}\n按键char:{1}\n按键keysym:{2}\n".format(event.keycode,event.char,event.keysym))

# 按键A/a测试
def keyboardTest_A(event):
    print("your press A/a")
def keyboardTest_DoubleA(event):
    print("your press A/a twice times")
def keyboardTest_CtrlA(event):
    print("your press ctrl+A/a")

# 进入c2组件区域测试
def enterTest(event):
    print("event_x:{0},event_y:{1}".format(event.x_root,event.y_root))

# 点击触发事件
c1.bind("<Button-1>",mouseTest)

# 拖动触发事件
c2.bind("<B1-Motion>",mouseDrag)

# 键盘触发事件,一个个测试
# 一般来说,键盘的按键都是绑定主界面
Clichong.bind("<KeyPress>",keyboardTest)
Clichong.bind("<KeyPress-a>",keyboardTest_A)
Clichong.bind("<KeyPress-A>",keyboardTest_A)
Clichong.bind("<Double-KeyPress-a>",keyboardTest_DoubleA)
Clichong.bind("<Control-KeyPress-a>",keyboardTest_CtrlA)

# 鼠标指针进入某一组件区域测试
c2.bind("<Enter>",enterTest)

Clichong.mainloop()

ここに画像の説明を挿入

演習4:パラメーターを渡すラムダ式

ラムダ式は無名関数を定義します。これは、単純な入力パラメーターと結果を返す単純な計算にのみ適しており、複雑な関数には適していません。lambdaによって定義された無名関数にも入力と出力がありますが、名前はありません。
構文形式は次のとおりです。ラムダパラメーター値リスト:式

  • パラメータ値リストが入力です。
  • 式の計算の構造は出力です。
    ここに画像の説明を挿入

from tkinter import *

Clichong = Tk()
Clichong.geometry("270x100")

def MyTest(str1,str2):
    print(str1,"make friend with",str2)

# 使用lambda关键字可以实现传递多个参数操作
Button(Clichong,text="bt1",command=lambda :MyTest("Clichong","Lawrence")).pack()

t1 = lambda x,y:x**y
t2 = lambda :MyTest("A","B")
print("t1(2,3):",t1(2,3),"\n","MyTest(A,B)",t2)

Clichong.mainloop()

ここに画像の説明を挿入

演習5:複数のイベントバインディングメソッド
  • コンポーネントオブジェクトのバインド
  1. コマンド属性を介したバインド(単純でイベントオブジェクトを取得する必要がない場合に適しています)
    Button(root、text =” login”、command = login)
  2. bind()メソッドによるバインド(イベントオブジェクトの取得に適しています)
    c1 = Canvas(); c1.bind( ""、drawLine)

ps:
コマンドモードでバインドすると、イベントオブジェクトを直接取得できません ""
バインドモードでバインドすると、イベントオブジェクトを取得できます ""

  • コンポーネントクラスのバインド

オブジェクトのbind_class関数を呼び出して、コンポーネントクラスのすべてのコンポーネントをイベントにバインドします。w.bind_class( "Widget"、 "event"、eventhanler)
例:btn01.bind_class( "Button"、 ""、func)

前のポーカーのトランプの小さな例を参照してください。

from tkinter import *

Clichong = Tk()
Clichong.geometry("600x400+300+300")

myphoto = [PhotoImage(file="photo/puke/puke"+str(pukenumber+1)+".gif")for pukenumber in range(10)]
mypuke = [Label(Clichong,image=myphoto[i])for i in range(10)]

for i in range(10):
    mypuke[i].place(x=50+40*i,y=130)
    
def pukeoutfunction(event):
    print(event.widget.winfo_geometry())    
    print(event.widget.winfo_y())         
    if event.widget.winfo_y() == 130:
        event.widget.place(y=80)
    else:
        event.widget.place(y=130)

# 对label事件点击的绑定出牌操作,bind_class直接绑定label这整一类
mypuke[1].bind_class("Label","<Button-1>",pukeoutfunction)

Clichong.mainloop()
演習6:OptionMenu選択項目

前書き:

class OptionMenu(Menubutton):
    """OptionMenu which allows the user to select a value from a menu."""
    def __init__(self, master, variable, value, *values, **kwargs):
        """Construct an optionmenu widget with the parent MASTER, with
        the resource textvariable set to VARIABLE, the initially selected
        value VALUE, the other menu values VALUES and an additional
        keyword argument command."""
        kw = {"borderwidth": 2, "textvariable": variable,
              "indicatoron": 1, "relief": RAISED, "anchor": "c",
              "highlightthickness": 2}

テスト:


from tkinter import *

Clichong = Tk()
Clichong.geometry("400x300+300+300")

# 设置变量,方便回去选择项获取的内容,与其他空间类型操作
opmfirstvar = StringVar()
opmfirstvar.set("蔬菜面")
opm1 = OptionMenu(Clichong,opmfirstvar,"蔬菜面","兰州拉面","豚骨拉面","地狱拉面")
opm1.place(x=50,y=30,width=120,height=40)

def ShowLabel():
    print(opmfirstvar.get())

bt1 = Button(Clichong,width=3,command=ShowLabel).place(x=50,y=100)

Clichong.mainloop()

ここに画像の説明を挿入

演習7:スライダーを動かしてスケールする

前書き:

class Scale(Widget):
    """Scale widget which can display a numerical scale."""
    def __init__(self, master=None, cnf={}, **kw):
        """Construct a scale widget with the parent MASTER.

        Valid resource names: activebackground, background, bigincrement, bd,
        bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
        highlightbackground, highlightcolor, highlightthickness, label,
        length, orient, relief, repeatdelay, repeatinterval, resolution,
        showvalue, sliderlength, sliderrelief, state, takefocus,
        tickinterval, to, troughcolor, variable, width."""
        Widget.__init__(self, master, 'scale', cnf, kw)

テスト:


from tkinter import *

Clichong = Tk()
Clichong.geometry("400x300")

lb1 = Label(Clichong,text="Clichong",width=10,height=2,font=("宋体",20))
lb1.pack()
# label不支持以下的操作:TypeError: 'NoneType' object does not support item assignment
# lb1["font"] = ("宋体",20)

# 通过函数传递当前值
def mytest(value):
    print(value)
    newFont = ("黑体", value)
    lb1.config(font=newFont)

sc1 = Scale(Clichong,from_=10,to=100,length=300,width=30,command=mytest)
# 组件Scale可以支持如下操作
sc1["orient"] = HORIZONTAL
sc1.pack()

Clichong.mainloop()


ここに画像の説明を挿入
調整:調整後:
ここに画像の説明を挿入

演習8:動的フォント調整のメソッドテスト

上記のフォント調整の失敗に基づいて、この部分は再度デバッグされます


from tkinter import *

Clichong = Tk()
Clichong.geometry("400x300")

lb1 = Label(Clichong,text="Clichong",width=10,height=2,font=("宋体",20))
lb1.pack()

# 经测试,以下两种动态调整字体的方法都可以
def func1():
    lb1["font"] = ("黑体", 40)
def func2():
    lb1.config(font=("黑体",30))

bt1 = Button(Clichong,command=func1).pack(side="left")
bt2 = Button(Clichong,command=func2).pack(side="left")
Clichong.mainloop()

ボタン1:
ここに画像の説明を挿入
ボタン2:
ここに画像の説明を挿入

演習9:色選択ボックスの基本的な使用法

色選択ボックスは、背景色、前景色、ペンの色、フォントの色などを設定するのに役立ちます。

# 颜色选择框

from tkinter import *
from tkinter.colorchooser import *

Clichong = Tk()
Clichong.geometry("400x300")

def mytest():
    # 设置初始选择的颜色是绿色,颜色框标题是"My color"
    cr = askcolor(color="green",title="My color")
    # 得出的结果是((128.5, 255.99609375, 255.99609375), '#80ffff')
    print(cr)

    # 设置背景颜色,以下两种方法均可
    Clichong["bg"] = cr[1]
    Clichong.config(bg = cr[1])

Button(Clichong,text="选择背景色",command=mytest).pack()

Clichong.mainloop()

色選択ボックスを表示します。
ここに画像の説明を挿入
[OK]をクリックして背景色を変更します
ここに画像の説明を挿入

演習10:ファイルダイアログの基本的な使用法

ファイルダイアログボックスは、視覚的な操作カタログと操作ファイルを実現するのに役立ちます。最後に、ファイルとディレクトリの情報をプログラムに渡します。ファイルダイアログには、次の一般的に使用される関数が含まれています:
ここに画像の説明を挿入
ここに画像の説明を挿入
名前付きパラメータオプションの一般的な値は次のとおりです:
ここに画像の説明を挿入

テスト1:選択したファイル名を返す
# 文件选择框

from tkinter import *
from  tkinter.filedialog import *

Clichong = Tk()
Clichong.geometry("400x300")

def mytest():
    askfile = askopenfilename(title="My File")
    lb1["text"] = askfile

Button(Clichong,command=mytest).pack()

lb1 = Label(Clichong,width=40,height=3,bg="green")
lb1.pack()
Clichong.mainloop()

ボタンをクリックしてファイル選択ボックスをポップアップします。選択後
ここに画像の説明を挿入
、ファイル名がラベルに表示されます
ここに画像の説明を挿入

テスト2:指定されたtxtファイルを開き、ファイルの内容をウィンドウに読み込みます
# 文件选择框

from tkinter import *
from  tkinter.filedialog import *

Clichong = Tk()
Clichong.geometry("400x300")

def mytest1():
    askfile = askopenfilename(title="My File")
    lb1["text"] = askfile

def mytest2():
    with askopenfile(title="File") as fd:
        lb2.config(text=fd.read())

Button(Clichong,command=mytest1).pack(side="left")
Button(Clichong,command=mytest2).pack(side="left")

lb1 = Label(Clichong,width=40,height=3,bg="pink")
lb1.pack()
lb2 = Label(Clichong,width=40,height=10,bg="blue")
lb2.pack()

Clichong.mainloop()

テストボタン1:
ここに画像の説明を挿入
出力ファイルパスキング
ここに画像の説明を挿入
テストボタン2:
ここに画像の説明を挿入
出力ファイルの内容
ここに画像の説明を挿入

演習11:単純な入力ダイアログ

simpledialog(シンプルなダイアログボックス)には、次の一般的に使用される関数が含まれてい
ここに画像の説明を挿入
ます。パラメーターの中で、titleはウィンドウのタイトルを表し、promptはプロンプトメッセージです。名前付きパラメーターkwはさまざまなオプションです:initialvalue(初期値)、minvalue(最小値)、maxvalue (最大値)。

# 颜色选择框

from tkinter import *
from tkinter.simpledialog import *

Clichong = Tk()
Clichong.geometry("400x300")

lb1 = Label(Clichong,width=40,height=3,bg= "green")
lb1.pack()
# Button(Clichong,text="选择背景色",command=mytest).pack()

getstr = askinteger(title="about age",prompt="input your age",initialvalue=0,minvalue=0,maxvalue=100)
lb1.config(text=getstr)

Clichong.mainloop()

ここに画像の説明を挿入
100を超えると警告が表示されます。
ここに画像の説明を挿入
ここに画像の説明を挿入

演習12:一般的なメッセージボックス

メッセージボックス(一般的なメッセージボックス)は、ユーザーとの簡単な対話に使用されます。ユーザーは[OK]と[キャンセル]をクリックします。メッセージボックスの一般的な機能は次のとおりです。
ここに画像の説明を挿入
テストコード:


from tkinter import *
from tkinter.messagebox import *

Clichong = Tk()
Clichong.geometry("400x300")

# box1 = askokcancel(Clichong,"你是男的女的")
# box2 = askquestion(title="问题1",message="你是男的女的")
# box3 = askyesnocancel(title="问题1",message="你是男的女的")
# box4 = showinfo(title="问题1",message="你是男的女的")
box5 = showerror(title="问题1",message="你是男的女的")

Clichong.mainloop()

ここに画像の説明を挿入

  • ttkサブモジュール制御

以前に学習したコンポーネントはtkinterモジュールの下のコンポーネントであり、全体的なスタイルは古くて醜​​いです。この欠点を補うために、ttkコンポーネントが導入されました。ttkコンポーネントは、より美しく、より強力です。Comboboxを使用して元のリストボックスを置き換え、LabeledScale(ラベル付きスケール)、Notebook(マルチドキュメントウィンドウ)、Progressbar(プログレスバー)、Treeview(数値)およびその他のコンポーネントを追加します。ttkモジュールをインポートする限り、
ttkコンポーネントと通常のTkinterコンポーネントの使用に大きな
違いはありません

おすすめ

転載: blog.csdn.net/weixin_44751294/article/details/110236353