Maison >développement back-end >Tutoriel Python >Comment implémenter la commutation de trame dans la programmation GUI Python Tkinter
Habituellement, une application Tkinter se compose de plusieurs Frames. Et vous devez souvent basculer entre les frames pour afficher le frame correspondant à la sélection de l'utilisateur.
Tkinter permet d'empiler des cadres les uns sur les autres. Pour afficher un cadre spécifique, placez-en simplement un sur un autre dans l'ordre d'empilage. Le cadre supérieur sera visible.
Pour placer le Frame au-dessus, vous pouvez utiliser la méthode tkraise() du widget Frame, comme indiqué ci-dessous :
frame.tkraise()
Ce qui suit implémentera une petite application de conversion de température, en utilisant Fahrenheit et Celsius. températures respectivement. Deux cadres différents, la fenêtre de l'interface utilisateur est composée comme suit :
ConverterFrame aura deux instances, l'une convertit la température de Fahrenheit en Celsius, l'autre convertit la température de Celsius en Fahrenheit :
La première étape consiste à définir une classe TemperatureConverter avec deux méthodes statiques : fahrenheit_to_celsius et celsius_to_fahrenheit.
class TemperatureConverter: @staticmethod def fahrenheit_to_celsius(f, format=True): result = (f - 32) * 5/9 if format: return f'{f} Fahrenheit = {result:.2f} Celsius' return result @staticmethod def celsius_to_fahrenheit(c, format=True): result = c * 9/5 + 32 if format: return f'{c} Celsius = {result:.2f} Fahrenheit' return result
Les méthodes fahrenheit_to_celsius et celsius_to_fahrenheit renverront une chaîne formatée si le deuxième argument est omis ou si True leur est transmis. Sinon, ils renvoient le résultat sous forme de nombre.
Deuxième étape, définissez le ConverterFrame qui affichera l'interface utilisateur pour convertir la température de Fahrenheit en Celsius et vice versa.
Pour ce faire, rendez le ConverterFrame plus flexible en ajoutant les paramètres suivants à la méthode __init__()
:
Chaînes qui seront affichées en Fahrenheit et Celsius
Fonction de rappel pour convertir la température.
class ConverterFrame(ttk.Frame): def __init__(self, container, unit_from, converter): super().__init__(container) self.unit_from = unit_from self.converter = converter # field options options = {'padx': 5, 'pady': 0} # temperature label self.temperature_label = ttk.Label(self, text=self.unit_from) self.temperature_label.grid(column=0, row=0, sticky='w', **options) # temperature entry self.temperature = tk.StringVar() self.temperature_entry = ttk.Entry(self, textvariable=self.temperature) self.temperature_entry.grid(column=1, row=0, sticky='w', **options) self.temperature_entry.focus() # button self.convert_button = ttk.Button(self, text='Convert') self.convert_button.grid(column=2, row=0, sticky='w', **options) self.convert_button.configure(command=self.convert) # result label self.result_label = ttk.Label(self) self.result_label.grid(row=1, columnspan=3, **options) # add padding to the frame and show it self.grid(column=0, row=0, padx=5, pady=5, sticky="nsew") def convert(self, event=None): """ Handle button click event """ try: input_value = float(self.temperature.get()) result = self.converter(input_value) self.result_label.config(text=result) except ValueError as error: showerror(title='Error', message=error) def reset(self): self.temperature_entry.delete(0, "end") self.result_label.text = ''
Comment fonctionne le code ci-dessus ?
1) Utilisez le paramètre unit_from pour afficher l'étiquette de température.
2) Appelez le rappel self.convert dans la méthode convert() pour convertir la température d'une unité à une autre.
3) Définissez la méthode reset() pour effacer les widgets d'entrée et les étiquettes de résultat lorsque Frame passe de l'un à l'autre.
Troisièmement, définissez une classe ControlFrame qui affiche des boutons radio pour sélectionner le cadre à afficher. La classe ControFrame hérite de ttk.LabelFrame.
class ControlFrame(ttk.LabelFrame): def __init__(self, container): super().__init__(container) self['text'] = 'Options' # radio buttons self.selected_value = tk.IntVar() ttk.Radiobutton( self, text='F to C', value=0, variable=self.selected_value, command=self.change_frame).grid(column=0, row=0, padx=5, pady=5) ttk.Radiobutton( self, text='C to F', value=1, variable=self.selected_value, command=self.change_frame).grid(column=1, row=0, padx=5, pady=5) self.grid(column=0, row=1, padx=5, pady=5, sticky='ew') # initialize frames self.frames = {} self.frames[0] = ConverterFrame( container, 'Fahrenheit', TemperatureConverter.fahrenheit_to_celsius) self.frames[1] = ConverterFrame( container, 'Celsius', TemperatureConverter.celsius_to_fahrenheit) self.change_frame() def change_frame(self): frame = self.frames[self.selected_value.get()] frame.reset() frame.tkraise()
Comment fonctionne le code ci-dessus ?
Chaque bouton radio a une valeur de 0 ou 1.
Créez deux instances de la classe ConverterFrame, l'une chargée de convertir la température de Fahrenheit en Celsius et l'autre responsable de la conversion de la température de Celsius en Fahrenheit. De plus, définissez un dictionnaire pour stocker ces Frames. Les touches du Frame sont les mêmes que les valeurs des boutons radio.
Lorsque vous cliquez sur un bouton radio, la méthode change_frame() est appelée pour sélectionner le Frame correspondant dans le dictionnaire en fonction de la valeur du bouton sélectionné.
Appelez la méthode reset() de Frame pour réinitialiser les champs de saisie et les étiquettes de résultat. Et appelle également la méthode tkraise() pour afficher le Frame.
Quatrièmement, définissez la classe App héritée de la classe tk.Tk :
class App(tk.Tk): def __init__(self): super().__init__() self.title('Temperature Converter') self.geometry('300x120') self.resizable(False, False)
Enfin, démarrez le programme
if __name__ == "__main__": app = App() ControlFrame(app) app.mainloop()
L'intégration du code est la suivante :
import tkinter as tk from tkinter import ttk from tkinter.messagebox import showerror class TemperatureConverter: @staticmethod def fahrenheit_to_celsius(f, format=True): result = (f - 32) * 5/9 if format: return f'{f} Fahrenheit = {result:.2f} Celsius' return result @staticmethod def celsius_to_fahrenheit(c, format=True): result = c * 9/5 + 32 if format: return f'{c} Celsius = {result:.2f} Fahrenheit' return result class ConverterFrame(ttk.Frame): def __init__(self, container, unit_from, converter): super().__init__(container) self.unit_from = unit_from self.converter = converter # field options options = {'padx': 5, 'pady': 0} # temperature label self.temperature_label = ttk.Label(self, text=self.unit_from) self.temperature_label.grid(column=0, row=0, sticky='w', **options) # temperature entry self.temperature = tk.StringVar() self.temperature_entry = ttk.Entry(self, textvariable=self.temperature) self.temperature_entry.grid(column=1, row=0, sticky='w', **options) self.temperature_entry.focus() # button self.convert_button = ttk.Button(self, text='Convert') self.convert_button.grid(column=2, row=0, sticky='w', **options) self.convert_button.configure(command=self.convert) # result label self.result_label = ttk.Label(self) self.result_label.grid(row=1, columnspan=3, **options) # add padding to the frame and show it self.grid(column=0, row=0, padx=5, pady=5, sticky="nsew") def convert(self, event=None): """ Handle button click event """ try: input_value = float(self.temperature.get()) result = self.converter(input_value) self.result_label.config(text=result) except ValueError as error: showerror(title='Error', message=error) def reset(self): self.temperature_entry.delete(0, "end") self.result_label.text = '' class ControlFrame(ttk.LabelFrame): def __init__(self, container): super().__init__(container) self['text'] = 'Options' # radio buttons self.selected_value = tk.IntVar() ttk.Radiobutton( self, text='F to C', value=0, variable=self.selected_value, command=self.change_frame).grid(column=0, row=0, padx=5, pady=5) ttk.Radiobutton( self, text='C to F', value=1, variable=self.selected_value, command=self.change_frame).grid(column=1, row=0, padx=5, pady=5) self.grid(column=0, row=1, padx=5, pady=5, sticky='ew') # initialize frames self.frames = {} self.frames[0] = ConverterFrame( container, 'Fahrenheit', TemperatureConverter.fahrenheit_to_celsius) self.frames[1] = ConverterFrame( container, 'Celsius', TemperatureConverter.celsius_to_fahrenheit) self.change_frame() def change_frame(self): frame = self.frames[self.selected_value.get()] frame.reset() frame.tkraise() class App(tk.Tk): def __init__(self): super().__init__() self.title('Temperature Converter') self.geometry('480x240') self.resizable(False, False) if __name__ == "__main__": app = App() ControlFrame(app) app.mainloop()
Les résultats d'exécution sont les suivants :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!