Python kleines Übungs-GUI-Design

Übung 1: Verwendung von Leinwand

Testen Sie, um gerade Linien, Kreise, Halbkreise, Dreiecke und andere Bilder zu zeichnen oder Bilder einzufügen


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()

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

Übung 2: Üben Sie drei Layout-Manager

tkinter bietet drei Arten von Managern: Pack, Grid und Place.

1. Grid Layout Manager

Rastertabellenlayout unter Verwendung der Tabellenstruktur zum Organisieren von Komponenten. Die Position von Unterkomponenten wird durch Zeilen- und Spaltenzellen bestimmt und kann Zeilen und Spalten umfassen, um komplexe Layouts zu erzielen.
Fügen Sie hier eine Bildbeschreibung ein
Test 1: Schreiben Sie eine einfache Anmeldeschnittstelle

#使用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()

Fügen Sie hier eine Bildbeschreibung ein
Test 2: Schreiben Sie ein einfaches Layout eines Taschenrechners

#使用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()

Fügen Sie hier eine Bildbeschreibung ein

2. Pack Layout Manager

Pack fügt die untergeordneten Komponenten der übergeordneten Komponente in der Reihenfolge der Komponentenerstellung hinzu und ordnet sie auf natürliche Weise in vertikaler oder horizontaler Richtung an. Wenn Sie keine Optionen angeben, werden in der übergeordneten Komponente standardmäßig Komponenten vertikal von oben nach unten hinzugefügt.
Fügen Sie hier eine Bildbeschreibung ein
Test: Erstellen des Klaviertastenlayouts

#使用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()

Fügen Sie hier eine Bildbeschreibung ein

3. Platzieren Sie den Layout-Manager

Der Platzlayout-Manager kann die Position von Komponenten über Koordinaten präzise steuern, was für einige Szenarien mit flexibleren Layouts geeignet ist.
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Test 1: Testen Sie einfach die Platzkomponente

# 测试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()

Fügen Sie hier eine Bildbeschreibung ein
Test 2: Einstellungen für den Kartenspielbetrieb

# 扑克出牌

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()

Ausgangszustand
Fügen Sie hier eine Bildbeschreibung ein
Klicken Sie auf eine Karte, und
Fügen Sie hier eine Bildbeschreibung ein
klicken Sie erneut, um sie zurückzunehmen
Fügen Sie hier eine Bildbeschreibung ein

Übung 3: Verwendung von Mausereignissen und Tastaturereignissen

  Der gesamte Lebenszyklus einer GUI-Anwendung befindet sich in einer Ereignisschleife. Es wartet auf das Eintreten des Ereignisses und behandelt es entsprechend. Tkinter bietet einen Mechanismus zum Behandeln verwandter Ereignisse. Handle-Funktionen können an verschiedene Ereignisse jedes Steuerelements gebunden werden. widget.bind (Ereignis, Handler) Wenn ein verwandtes Ereignis auftritt, wird die Handlerfunktion ausgelöst und das Ereignisobjektereignis an die Handlerfunktion übergeben.

Maus- und Tastaturereignisse:
Fügen Sie hier eine Bildbeschreibung ein
Allgemeine Attribute von Ereignisobjekten:
Fügen Sie hier eine Bildbeschreibung ein


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()

Fügen Sie hier eine Bildbeschreibung ein

Übung 4: Lambda-Ausdrücke zum Übergeben von Parametern

Der Lambda-Ausdruck definiert eine anonyme Funktion, die nur für einfache Eingabeparameter und einfache Berechnungen geeignet ist, um Ergebnisse zurückzugeben, die für komplexe Funktionen nicht geeignet ist. Die von Lambda definierte anonyme Funktion hat ebenfalls Ein- und Ausgänge, aber keinen Namen.
Das Syntaxformat lautet wie folgt: Lambda-Parameterwertliste: Ausdruck

  • Die Parameterwertliste ist die Eingabe.
  • Die Struktur der Ausdrucksberechnung ist die Ausgabe.
    Fügen Sie hier eine Bildbeschreibung ein

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()

Fügen Sie hier eine Bildbeschreibung ein

Übung 5: Mehrere Ereignisbindungsmethoden
  • Bindung von Komponentenobjekten
  1. Bindung über das Befehlsattribut (geeignet für einfaches und nicht erforderliches Abrufen des Ereignisobjekts)
    Schaltfläche (root, text = ”login”, command = login)
  2. Bindung über die bind () -Methode (geeignet zum
    Abrufen von Ereignisobjekten) c1 = Canvas (); c1.bind ("", drawLine)

ps:
Bindung im Befehlsmodus, Sie können das Ereignisobjekt nicht direkt erhalten. ""
Bindung im Bindungsmodus, Sie können das Ereignisobjekt erhalten. ""

  • Bindung von Komponentenklassen

Rufen Sie die Funktion bind_class des Objekts auf, um alle Komponenten der Komponentenklasse an Ereignisse zu binden: w.bind_class ("Widget", "event", eventhanler)
Beispiel: btn01.bind_class ("Button", "", func)

Sehen Sie sich das kleine Beispiel für Spielkarten im vorherigen Poker an:

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()
Übung 6: Auswahlelemente des Optionsmenüs

Einführung:

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}

Prüfung:


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()

Fügen Sie hier eine Bildbeschreibung ein

Übung 7: Skalieren Sie das Bewegen des Schiebereglers

Einführung:

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)

Prüfung:


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()

Vor der
Fügen Sie hier eine Bildbeschreibung ein
Einstellung: Nach der Einstellung:
Fügen Sie hier eine Bildbeschreibung ein

Übung 8: Methodentest der dynamischen Schriftanpassung

Aufgrund des Fehlschlags der obigen Schriftartenanpassung wird dieser Teil erneut getestet


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()

Taste 1:
Fügen Sie hier eine Bildbeschreibung ein
Taste 2:
Fügen Sie hier eine Bildbeschreibung ein

Übung 9: Grundlegende Verwendung des Farbauswahlfelds

Das Farbauswahlfeld kann uns beim Einstellen der Hintergrundfarbe, der Vordergrundfarbe, der Stiftfarbe, der Schriftfarbe usw. helfen.

# 颜色选择框

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()

Rufen Sie das Farbauswahlfeld auf:
Fügen Sie hier eine Bildbeschreibung ein
Klicken Sie auf OK, um die Hintergrundfarbe zu ändern
Fügen Sie hier eine Bildbeschreibung ein

Übung 10: Grundlegende Verwendung des Dateidialogs

Das Dialogfeld "Datei" hilft uns bei der Realisierung des visuellen Operationskatalogs und der Operationsdateien. Übergeben Sie abschließend die Datei- und Verzeichnisinformationen an das Programm. Der Dateidialog enthält die folgenden häufig verwendeten Funktionen:
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Die allgemeinen Werte der genannten Parameteroptionen lauten wie folgt:
Fügen Sie hier eine Bildbeschreibung ein

Test 1: Geben Sie den ausgewählten Dateinamen zurück
# 文件选择框

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()

Klicken Sie auf die Schaltfläche, um das Dateiauswahlfeld aufzurufen: Nach der
Fügen Sie hier eine Bildbeschreibung ein
Auswahl wird der Dateiname auf dem Etikett angezeigt
Fügen Sie hier eine Bildbeschreibung ein

Test 2: Öffnen Sie die angegebene txt-Datei und lesen Sie den Inhalt der Datei in das Fenster
# 文件选择框

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()

Testschaltfläche 1:
Fügen Sie hier eine Bildbeschreibung ein
Pfad der Ausgabedatei King
Fügen Sie hier eine Bildbeschreibung ein
Testschaltfläche 2:
Fügen Sie hier eine Bildbeschreibung ein
Inhalt der Ausgabedatei
Fügen Sie hier eine Bildbeschreibung ein

Übung 11: Einfacher Eingabedialog

Der vereinfachte Dialog (einfaches Dialogfeld) enthält die folgenden häufig verwendeten Funktionen: Unter den
Fügen Sie hier eine Bildbeschreibung ein
Parametern steht der Titel für den Fenstertitel, die Eingabeaufforderung für die Eingabeaufforderung und der benannte Parameter kw für verschiedene Optionen: Anfangswert (Anfangswert), Minimalwert (Minimalwert), Maximalwert (höchster Wert).

# 颜色选择框

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()

Fügen Sie hier eine Bildbeschreibung ein
Mehr als 100 werden warnen:
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

Übung 12: Allgemeines Meldungsfeld

Das Nachrichtenfeld (allgemeines Nachrichtenfeld) wird für die einfache Interaktion mit dem Benutzer verwendet. Der Benutzer klickt auf OK und auf Abbrechen. Die allgemeinen Funktionen von messagebox sind wie folgt aufgeführt:
Fügen Sie hier eine Bildbeschreibung ein
Testcode:


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()

Fügen Sie hier eine Bildbeschreibung ein

  • ttk Submodulsteuerung

Die Komponenten, die wir zuvor gelernt haben, sind die Komponenten unter dem tkinter-Modul, und der Gesamtstil ist älter und hässlicher. Um diesen Mangel auszugleichen, wurde die ttk-Komponente eingeführt. ttk-Komponenten sind schöner und leistungsfähiger. Verwenden Sie Combobox, um die ursprüngliche Listbox zu ersetzen, und fügen Sie LabeledScale (beschriftet Scale), Notebook (Fenster mit mehreren Dokumenten), Progressbar (Fortschrittsbalken), Treeview (Nummer) und andere Komponenten hinzu.
Es gibt keinen großen
Unterschied zwischen der Verwendung von ttk-Komponenten und normalen Tkinter-Komponenten , solange Sie das ttk-Modul importieren.

Ich denke du magst

Origin blog.csdn.net/weixin_44751294/article/details/110236353
Empfohlen
Rangfolge