--Visual Studio (VB.NET), Android Studio (Java), XCode (Swift) sont faciles à développer / développer une interface graphique avec le concepteur GUI standard (l'application de bureau migre de VB.NET vers Java, C # est Unity Je l'utilise seulement) --En Java, AWT / Swing a été construit comme une interface graphique sans utiliser de concepteur (mise en page) ―― Depuis que le langage principal est passé de Java à Python, je n'ai fait que des outils CUI / Web, donc je veux également créer une interface graphique de bureau.
Ce n'est pas très performant (il y a des inconvénients en termes de transparence et de fonctions standards), mais comme c'est standard, je vais le résumer pour moi-même sous forme de mémorandum.
Quand j'essaye de quitter avec \ # Ctrl + C, il est ennuyeux qu'il ne réponde pas tant que je n'ai pas touché la fenêtre
import tkinter as tk
root = tk.Tk() # Window
root.title('Hello Window') # Window title
root.geometry('%dx%d' % (400, 400)) # Window size (width, height)
#Initialisez et placez le widget ici
root.mainloop()
Bloquer avec root.mainloop ()
. Quittez la boucle principale lorsque la fenêtre est fermée.
Pour être précis, Tk semble gérer la boucle principale de Tkinter plutôt que Window. Vous pouvez créer les deuxième et troisième fenêtres avec tk.Toplevel
lorsque vous créez des fenêtres multiples pour utiliser modal etc. (équivalent à Form = VB.NET, Frame = Java). Dans le cas de Java, je m'en fichais car je pense que le thread qui exécute la boucle pour l'interface graphique se lève (il reste en vie même si le thread principal qui exécute la fonction principale se termine), mais dans le cas de Tkinter, il est explicite. Il semble être géré de manière ciblée.
Si vous ne voulez pas que Tk existe en tant que fenêtre racine (en utilisant tk.Toplevel), vous pouvez le supprimer avec root.withdraw ()
. Cependant, la logique de "Fenêtre fermée = Fin de la boucle principale = Fin du programme" ne fonctionnera pas (rappelle la DefaultCloseOperation de Swing), donc root.destroy (me rappelle la DefaultCloseOperation de Swing) lorsque l'application se termine. )
Appelez.
Affichez une fenêtre avec tk.Toplevel pour que la boucle principale se termine lorsqu'une fenêtre spécifique est fermée.
import tkinter as tk
root = tk.Tk()
root.withdraw()
window = tk.Toplevel(root)
window.title('Hello Window')
window.geometry('%dx%d' % (400, 400))
window.protocol('WM_DELETE_WINDOW', root.destroy)
#Initialisez et placez le widget ici
root.mainloop()
La fermeture de window
peut être détectée par window.protocol ('WM_DELETE_WINDOW', handler_func)
(correspondant à WindowListener \ #windowClosing of Swing).
window.protocol('WM_DELETE_WINDOW', root.destroy)
Après tout, dans une application comme une seule fenêtre + modale, il serait plus simple de traiter Tk comme la fenêtre principale avec obéissance.
frame = tk.Frame(root)
# frame = tk.Frame(root, bg='#FF00FF')
# frame['bg'] = '#FF00FF'
frame.place(x=8, y=8, width=200, height=200)
Panel(VB.NET/Java)/UIView(iOS)/ViewGroup(Android)的なやつ。Widgetのコンストラクタにbgとしてカラーコードを渡すと背景色を設定できる。初期化後に背景色を設定したい場合はディスクリプタ経由(widget['bg']
)で設定できる。
Label Label(VB.NET/Java)/UILabel(iOS)/TextView(Android)的なやつ。
label = tk.Label(root, text='Hello')
# label['text'] = 'Another text'
label.place(x=8, y=8)
def onHelloClicked(event):
print(event) # <ButtonPress event num=BUTTON_NUM x=MOUSE_X y=MOUSE_Y>
# print(event.x, event.y, event.num)
button = tk.Button(root, text='Hello')
# button = tk.Button(root, text='Hello', width=10)
# button['text'] = 'Another text'
button.bind('<Button-1>', onHelloClicked)
# button.bind('<Button-2>', onHelloClicked)
# button.bind('<Button-3>', onHelloClicked)
# button.bind('<Button>', onHelloClicked)
button.place(x=8, y=8)
# button.place(x=8, y=8, width=60)
# button.place(x=8, y=8, width=60, height=31)
Vous pouvez passer width
au constructeur de Widget, mais l'unité n'est pas en pixel et c'est difficile à comprendre (nombre de caractères?).
Vous pouvez enregistrer un gestionnaire d'événements avec bind. <Button - *>
représente un clic sur le bouton de la souris (déroutant, mais sans rapport avec le tk.Button du widget). Faites un clic gauche sur « (ʻevent.num = 1
lors d'un clic gauche, ʻevent.num = 3lors d'un clic droit. C'est déroutant, mais pas le nombre de clics). Vous pouvez également obtenir tous les clics de souris en spécifiant
# initialize button
# place button
root.update()
print(button.winfo_width(), button.winfo_height())
# root.mainloop()
Dans mon environnement, quand j'ai passé width à Button dans le constructeur, winfo_width était 36+ (width-1) * 8
. La valeur par défaut winfo_width (0 caractère) était de 28 (pixel). Si aucune largeur n'est définie, winfo_width changera en fonction de la chaîne de caractères donnée. winfo_height vaut 31 (pixel) lorsqu'aucun saut de ligne n'est inséré, et lorsqu'un saut de ligne est inséré, le saut de ligne est reflété dans l'affichage et winfo_height est automatiquement développé.
from PIL import Image, ImageTk
# initialize root
image = Image.new('RGB', (128, 128), color=(255, 0, 255)) #Image appropriée
image_tk = ImageTk.PhotoImage(image)
image_view = tk.Label(root, image=image_tk)
image_view.place(x=8, y=8)
# root.mainloop()
entry = tk.Entry(root, width=10)
entry.insert(tk.END, 'Hello') #valeur initiale
print(entry.get()) # 'Hello'
entry.delete(0, tk.END) #clair
print(entry.get()) # ''
entry.place(x=8, y=8)
La valeur saisie peut être obtenue avec ʻentry.get () `.
text = tk.Text(root, width=30, height=10)
text.insert(tk.END, 'Hello') #valeur initiale
print(text.get('1.0', tk.END)) # 'Hello'
text.delete('1.0', tk.END) #clair
print(text.get('1.0', tk.END)) # ''
text.place(x=8, y=8)
Même si le nombre de lignes dépassait la hauteur, la barre de défilement n'apparaissait pas automatiquement. De plus, Ctrl + A ne fonctionnait pas (passer au début de la ligne?), Et bien que le raccourci couper-coller et le presse-papiers puissent être utilisés, le comportement lors de la sélection + collage (Ctrl + V) était étrange (le texte sélectionné n'était pas écrasé). Rester). Simple sans menu contextuel.
from tkinter.scrolledtext import ScrolledText
text = ScrolledText(root, width=30, height=10)
#Le reste est le même
def onKeyPressed(event):
print(event)
# <KeyPress event keysym=a keycode=38 char='a' x=205 y=132>
# <KeyPress event keysym=Shift_L keycode=50 x=442 y=272>
# <KeyPress event state=Shift keysym=A keycode=38 char='A' x=127 y=183>
# print(event.keycode, event.char, event.state)
#l'état est une valeur numérique (modificateur)
#Par défaut 0
#Maj 1 (0b0001), Ctrl 4 (0b0100), Alt 8 (0b1000)
# Shift+Alt 9 (0b1001), Win+Passez à 65 (0b01000001).
root.bind('<Key>', onKeyPressed)
Vous pouvez verser en utilisant le pack et la grille pour le placement des widgets.
widget.pack_forget()
2020/02/02 Addendum: Même si j'ai appliqué pack_forget à celui mis en place, il n'a pas bien disparu. Il semble bon d'utiliser «destroy».
widget.destroy()
root.attributes('-fullscreen', True)
# root.update()
# print(root.winfo_width(), root.winfo_height())
Fermez avec Alt + F4.
root.wm_attributes('-topmost', 1)
root.bind('<Escape>', lambda e: root.destroy())
# root.bind('<Key-Escape>', lambda e: root.destroy())
root.bind('<Control-w>', lambda e: root.destroy())
Combobox
Il semble y avoir FileChooser, ColorPicker, MessageBox, etc.
Recommended Posts