Calculadora GUI utilizando Tkinter -- python campo con python-3.x campo con calculator campo con gui campo con tkinter camp codereview Relacionados El problema

GUI Calculator using tkinter


6
vote

problema

Español

Este es mi programa Python para una calculadora GUI hecha con el módulo Tkinter. Esto me tomó unos 2 días para completar. Sin embargo, todavía creo que hay espacio para mejorar. Me falta algunos otros botones, y me planeo agregarlos más adelante. Además, no estaba seguro de si debo usar el estilo predeterminado de Tkinter o usar el estilo TTK (que se ve mejor en mi opinión). No obstante, solía el estilo predeterminado solo para probarlo de todos modos, pero ¿es mejor este estilo o el estilo TTK? Por favor, dame consejos y consejos que puedas sobre este tema.

  <?php include 'includes/phpScripts/profile.php';  $title = "--- Profile: " . $employee->display_name(); $description = "--- Profile: " . $employee->display_name();  include 'includes/headerFooters/mainHeader.php';  ?>  <div id="columnContainer">   <div id='centerColumn'>     <h1><?=$employee->display_name();?></h1>      <?=$employee->display_photo();?>      <div class='contactContainer'>       <?php         foreach($employee->display_departments() as $dept) {           echo "<h3>$dept</h3>";         }       ?>        <p>         <?php            $firstJob = true;           foreach($employee->display_jobs() as $job) {             if($firstJob) {               $firstJob = false;             }             else {               echo ", ";             }             echo $job;            }         ?>       </p>        <p>         <strong>Phone: </strong><?=$employee->display_phone();?><br>         <strong>Fax: </strong><?=$employee->display_fax();?><br>         <strong>E-mail: </strong><br><?=$employee->display_email();?>       </p>        <p><?=$employee->display_address();?></p>        <div class='clearfix'></div>     </div>   </div>    ... </div>  <?php include('includes/headerFooters/mainFooter.php'); ?> 4  
Original en ingles

This is my python program for a GUI Calculator made using the tkinter module. This took me about 2 days to complete. However, I still believe that there is room for improvement. I am missing a few other buttons, and I do plan to add them later on. Also, I was unsure whether I should use the default style of tkinter or to use the ttk style (which looks better in my opinion). Nonetheless, I used to the default style just to test it out anyway, but is this style better or the ttk style better? Please give me any tips and advice you can on this topic.

# Calculator made using pythons tkinter module # Author - Mohamed Akil  from tkinter import *  class Application(Frame):     """ Main class for calculator"""      def __init__(self, master):         """ Initialise the Frame. """         super(Application, self).__init__(master)         self.task = ""         self.UserIn = StringVar()         self.grid()         self.create_widgets()      def create_widgets(self):         """ Create all the buttons for calculator. """         # User input stored as an Entry widget.          self.user_input = Entry(self, bg = "#5BC8AC", bd = 29,          insertwidth = 4, width = 24,         font = ("Verdana", 20, "bold"), textvariable = self.UserIn, justify = RIGHT)         self.user_input.grid(columnspan = 4)          self.user_input.insert(0, "0")          # Button for value 7         self.button1 = Button(self, bg = "#98DBC6", bd = 12,         text = "7", padx = 33, pady = 25, font = ("Helvetica", 20, "bold"),          command = lambda : self.buttonClick(7))         self.button1.grid(row = 2, column = 0, sticky = W)          # Button for value 8         self.button2 = Button(self, bg = "#98DBC6", bd = 12,          text = "8",  padx = 35, pady = 25,          command = lambda : self.buttonClick(8), font = ("Helvetica", 20, "bold"))         self.button2.grid(row = 2, column = 1, sticky = W)          # Button for value 9         self.button3 = Button(self, bg = "#98DBC6", bd = 12,          text = "9",  padx = 33, pady = 25,         command = lambda : self.buttonClick(9), font = ("Helvetica", 20, "bold"))         self.button3.grid(row = 2, column = 2, sticky = W)          # Button for value 4         self.button4 = Button(self, bg = "#98DBC6", bd = 12,         text = "4",  padx = 33, pady = 25,         command = lambda : self.buttonClick(4), font = ("Helvetica", 20, "bold"))         self.button4.grid(row = 3, column = 0, sticky = W)          # Button for value 5         self.button5 = Button(self, bg = "#98DBC6", bd = 12,          text = "5",  padx = 35, pady = 25,         command = lambda : self.buttonClick(5), font = ("Helvetica", 20, "bold"))         self.button5.grid(row = 3, column = 1, sticky = W)          # Button for value 6         self.button6 = Button(self, bg = "#98DBC6", bd = 12,          text = "6",  padx = 33, pady = 25,         command = lambda : self.buttonClick(6), font = ("Helvetica", 20, "bold"))         self.button6.grid(row = 3, column = 2, sticky = W)          # Button for value 1         self.button7 = Button(self, bg = "#98DBC6", bd = 12,          text = "1",  padx = 33, pady = 25,          command = lambda : self.buttonClick(1), font = ("Helvetica", 20, "bold"))         self.button7.grid(row = 4, column = 0, sticky = W)          # Button for value 2         self.button8 = Button(self, bg = "#98DBC6", bd = 12,          text = "2",  padx = 35, pady = 25,         command = lambda : self.buttonClick(2), font = ("Helvetica", 20, "bold"))         self.button8.grid(row = 4, column = 1, sticky = W)          # Button for value 3         self.button9 = Button(self, bg = "#98DBC6", bd = 12,          text = "3",  padx = 33, pady = 25,         command = lambda : self.buttonClick(3), font = ("Helvetica", 20, "bold"))         self.button9.grid(row = 4, column = 2, sticky = W)          # Button for value 0         self.button9 = Button(self, bg = "#98DBC6", bd = 12,          text = "0",  padx = 33, pady = 25,         command = lambda : self.buttonClick(0), font = ("Helvetica", 20, "bold"))         self.button9.grid(row = 5, column = 0, sticky = W)          # Operator buttons         # Addition button         self.Addbutton = Button(self, bg = "#98DBC6", bd = 12,          text = "+",  padx = 36, pady = 25,         command = lambda : self.buttonClick("+"), font = ("Helvetica", 20, "bold"))         self.Addbutton.grid(row = 2, column = 3, sticky = W)          # Subtraction button         self.Subbutton = Button(self, bg = "#98DBC6", bd = 12,          text = "-",  padx = 39, pady = 25,         command = lambda : self.buttonClick("-"), font = ("Helvetica", 20, "bold"))         self.Subbutton.grid(row = 3, column = 3, sticky = W)          # Multiplication button         self.Multbutton = Button(self, bg = "#98DBC6", bd = 12,          text = "*",  padx = 38, pady = 25,         command = lambda : self.buttonClick("*"), font = ("Helvetica", 20, "bold"))         self.Multbutton.grid(row = 4, column = 3, sticky = W)          # Division button         self.Divbutton = Button(self, bg = "#98DBC6", bd = 12,          text = "/",  padx = 39, pady = 25,         command = lambda : self.buttonClick("/"), font = ("Helvetica", 20, "bold"))         self.Divbutton.grid(row = 5, column = 3, sticky = W)          # Equal button         self.Equalbutton = Button(self, bg = "#E6D72A", bd = 12,          text = "=",  padx = 100, pady = 25,         command = self.CalculateTask, font = ("Helvetica", 20, "bold"))         self.Equalbutton.grid(row = 5, column = 1, sticky = W, columnspan = 2)          # Clear Button         self.Clearbutton = Button(self, bg = "#E6D72A", bd = 12,         text = "AC", font = ("Helvetica", 20, "bold"), width = 28, padx = 7, command = self.ClearDisplay)         self.Clearbutton.grid(row = 1, columnspan = 4, sticky = W)      def buttonClick(self, number):         self.task = str(self.task) + str(number)         self.UserIn.set(self.task)      def CalculateTask(self):         self.data = self.user_input.get()         try:             self.answer = eval(self.data)             self.displayText(self.answer)             self.task = self.answer          except SyntaxError as e:             self.displayText("Invalid Syntax!")             self.task = ""      def displayText(self, value):         self.user_input.delete(0, END)         self.user_input.insert(0, value)      def ClearDisplay(self):         self.task = ""         self.user_input.delete(0, END)         self.user_input.insert(0, "0")   calculator = Tk()  calculator.title("Calculator") app = Application(calculator) # Make window fixed (cannot be resized) calculator.resizable(width = False, height = False)  calculator.mainloop() 
              
   
   

Lista de respuestas

2
 
vote
vote
La mejor respuesta
 

Idealmente, debe tener al menos 2 clases: una para mantener las funciones que realizan diferentes acciones en la GUI, y la otra clase para dibujar la GUI en sí. A continuación, proporciono sugerencias para mejorar la segunda clase solo porque, para una calculadora de ejercicio, hay muchas más cosas para mejorar.

Evite las importaciones de comodines

Debe usar import tkinter as tk en lugar de from tkinter import * . Sé que la mayoría de los tutoriales enseñan lo contrario, pero esa es una mala opción porque puede llevar a los problemas de los espacios de nombres.

Duplicación de código

La forma en que creó los diferentes botones lo llevan a duplicar el código varias veces. Necesitas encontrar una manera de refactorizar tu código.

Mi enfoque para evitar es crear todos los botones dentro de una función de canto:

  def create_calculator_buttons_texts(self):        button_column = 0        button_row = 1        text_buttons = ('A', '789+', '456-', '123*', '0=/')        for button_rows in text_buttons:            for text_button in button_rows:                               self.configure_and_place_button(text_button, button_row, button_column)                button_column += 1            button_row += 1            button_column = 0   

¿Dónde 9988776655544333 es la función que decora los botones:

  def configure_and_place_button(self, text_button, button_row, button_column):        key = list(self.calculator_buttons_texts.keys())[list(self.calculator_buttons_texts.values()).index(text_button)]        self.calculator_buttons_texts[key] = tk.Button(self.master, text=text_button, bg="#5BC8AC", bd=12)        self.calculator_buttons_texts[key].config(padx=33, pady=25, font=("Helvetica", 20, "bold"))        self.calculator_buttons_texts[key].grid(row=button_row,column=button_column)        self.reconfigure_specific_buttons(key, text_button)   

Debido a que todos los botones están diseñados de la misma manera, debemos confiar en otra función para que estilan el / , AC6 y = Botones:

  def reconfigure_specific_buttons(self, key, text_button):        self.reconfigure_clear_button(key, text_button)        self.reconfigure_equals_button(key, text_button)             self.reconfigure_divide_button(key, text_button)   

Stick The Borrar botón a East y West

Por el momento, hay un espacio vacío feo a la derecha del botón AC : ingrese la descripción de la imagen aquí

Esto sucedió porque usó Sticky = W. Para remediar este problema, use from tkinter import *0 . Esto resultará en:

ingrese la descripción de la imagen aquí

Evite los espacios al codificar los operadores de TK.Class (Opciones)

Mientras que el espaciado es una buena práctica, especialmente en Python, debe evitarse al escribir un operador de opciones de clase / función de Tkinter (+ y =). Quiero decir, algo como esto:

  from tkinter import *1  

debe escribirse de esta manera:

  from tkinter import *2  

Respetar las convenciones de nombres

Le sugiero que eche un vistazo a PEP 8 para leer sobre las convenciones de nombres para las variables y funciones en Python. Por ejemplo, el from tkinter import *3 Simplemente mencionado anteriormente, debe escribirse from tkinter import *4 .

Código de clase GUI mejorada

Aquí hay una clase Calculator_GUI (). Como dije en el párrafo inicial, no estoy incorporando ninguna funcionalidad a esta GUI. Debe crear una clase diferente para manejar las funciones que realizan las diferentes operaciones.

primero, creo un módulo para guardar en algunos datos globales fey :

  from tkinter import *5  

Es mejor mantener estos datos sucios en un módulo separado para no contaminar su clase. Esto también le permitirá agregar botones de adición en el futuro si es necesario.

Aquí está la clase GUI:

  from tkinter import *6  
 

Ideally, you should have at least 2 classes: one to hold functions performing different actions on the GUI, and the other class to draw the GUI itself. Below, I provide suggestions to improve the second class ONLY because, for a performant calculator, there are much more things to improve.

Avoid wildcard imports

You should use import tkinter as tk instead of from tkinter import *. I know most tutorials teach the opposite, but that is a bad option because it can lead to namespaces problems.

Code duplication

The way you created the different buttons lead you to duplicate code several times. You need to find a way to refactor your code.

My approach to avoid that is to create all the buttons within a sing function:

def create_calculator_buttons_texts(self):        button_column = 0        button_row = 1        text_buttons = ('A', '789+', '456-', '123*', '0=/')        for button_rows in text_buttons:            for text_button in button_rows:                               self.configure_and_place_button(text_button, button_row, button_column)                button_column += 1            button_row += 1            button_column = 0 

Where configure_and_place_button() is the function that decorates the buttons:

def configure_and_place_button(self, text_button, button_row, button_column):        key = list(self.calculator_buttons_texts.keys())[list(self.calculator_buttons_texts.values()).index(text_button)]        self.calculator_buttons_texts[key] = tk.Button(self.master, text=text_button, bg="#5BC8AC", bd=12)        self.calculator_buttons_texts[key].config(padx=33, pady=25, font=("Helvetica", 20, "bold"))        self.calculator_buttons_texts[key].grid(row=button_row,column=button_column)        self.reconfigure_specific_buttons(key, text_button) 

Because all the buttons are designed the same way, we need to rely on an other function to to style the /, AC and = buttons:

def reconfigure_specific_buttons(self, key, text_button):        self.reconfigure_clear_button(key, text_button)        self.reconfigure_equals_button(key, text_button)             self.reconfigure_divide_button(key, text_button) 

Stick the clear button to East and West

For the moment, there is an ugly empty space on the right of AC button: enter image description here

This happened because you used sticky = W. To remedy to this problem, use sticky=tk.W+tk.E. This will result in:

enter image description here

Avoid spaces when coding tk.Class(options)'s operators

While spacing is a good practice, especially in Python, it should be avoided when writing a tkinter class/function options' operators (+ and =). I mean, something like this:

self.Equalbutton.grid(row = 5, column = 1, sticky = W, columnspan = 2) 

Should be written this way:

self.Equalbutton.grid(row=5, column=1, sticky=W, columnspan=2) 

Respect the naming conventions

I suggest you to take a look at PEP 8 to read about the naming conventions for variables and functions in Python. For example, the self.Equalbutton() just menioned above, should be written self.equal_button().

Improved GUI class code

Here is a Calculator_GUI() class. As I said in the opening paragraph, I am not incorporating any functionality to this GUI. You should create a different class to handle functions performing the different operations.

First, I create a module to save in some global ugly data:

calculator_buttons_texts ={    'clear':'A',    'zero':'0',    'one':'1',    'two':'2',    'three':'3',    'four':'4',    'five':'5',    'six':'6',    'seven':'7',    'eight':'8',    'nine':'9',    'plus':'+',    'minus':'-',    'multiply':'*',    'divide':'/',    'equal':'='            }    

It is better to keep this dirty data in a separate module in order not to pollute your class. This will also allow you to add addition buttons in the future if needed.

Here is the GUI class:

#!/usr/bin/env python # -*- coding: utf-8 -*-  import calculator_data     import tkinter as tk   class Calculator_Core:    def __init__(self):        # Do this yourself        pass  class Calculator(tk.Frame):     def __init__(self, master):        tk.Frame.__init__(self, master)        self.master = master         self.calculator_buttons_texts = calculator_data.calculator_buttons_texts         self.configure_gui()         self.create_calculator_widgets()            def configure_gui(self):        self.master.title('Calculator')        self.master.resizable(False, False)     def create_calculator_widgets(self):        self.create_calculator_input_field()        self.create_calculator_buttons_texts()     def create_calculator_buttons_texts(self):        button_column = 0        button_row = 1        text_buttons = ('A', '789+', '456-', '123*', '0=/')        for button_rows in text_buttons:            for text_button in button_rows:                               self.configure_and_place_button(text_button, button_row, button_column)                button_column += 1            button_row += 1            button_column = 0     def configure_and_place_button(self, text_button, button_row, button_column):        key = list(self.calculator_buttons_texts.keys())[list(self.calculator_buttons_texts.values()).index(text_button)]        self.calculator_buttons_texts[key] = tk.Button(self.master, text=text_button, bg="#5BC8AC", bd=12)        self.calculator_buttons_texts[key].config(padx=33, pady=25, font=("Helvetica", 20, "bold"))        self.calculator_buttons_texts[key].grid(row=button_row,column=button_column)        self.reconfigure_specific_buttons(key, text_button)        def reconfigure_specific_buttons(self, key, text_button):        self.reconfigure_clear_button(key, text_button)        self.reconfigure_equals_button(key, text_button)             self.reconfigure_divide_button(key, text_button)      def reconfigure_clear_button(self, key, text_button):        if text_button == 'A':            self.calculator_buttons_texts[key].config(bg='#E6D72A', text='AC')            self.calculator_buttons_texts[key].grid(columnspan=4, sticky=tk.W+tk.E)     def reconfigure_equals_button(self, key, text_button):        if text_button == '=':            self.calculator_buttons_texts[key].config(bg='#E6D72A')            self.calculator_buttons_texts[key].grid(columnspan=2, sticky=tk.W+tk.E)     def reconfigure_divide_button(self, key, text_button):        if text_button == '/':            self.calculator_buttons_texts[key].grid(column=3)       def create_calculator_input_field(self):        self.user_input = tk.Entry(self.master, justify=tk.RIGHT, width=24, insertwidth=4, bd=29)        self.user_input.grid(row=0, column=0, columnspan=4)        self.user_input.configure(font = ("Verdana", 20, "bold"), bg="#5BC8AC")        self.user_input.insert(0, "0")   if __name__ == "__main__":     root = tk.Tk()     Calculator(root)     root.mainloop() 
 
 
     
     

Relacionados problema

4  Hacer una lista de la entrada del usuario  ( Making a list from user input ) 
He escribido un programa que permite al usuario abrir su archivo de texto que se vería algo así: 1 2 3 4 5 6 Luego, le permitiría que el usuario ingres...

4  Abra una ventana de selección de archivos a la posición más alta de Jupyter Notebook  ( Open a file selection window to top most position from jupyter notebook ) 
Fondo Se me ocurrió esta solución a una pregunta que publiqué en StackOverflow . Utiliza Tkinter para crear una ventana de diálogo de selección de archivos...

3  Primer programa de Python: Calculadora básica  ( First python program basic calculator ) 
Quiero comenzar a aprender Python por diversión y, por lo tanto, podría profundizar en los proyectos de aprendizaje de la máquina más adelante en el futuro ta...

4  Formulario de entrada de datos simple que escribe datos a texto de texto  ( Simple data entry form that writes data to textfile ) 
Hice un formulario de entrada de datos que escribe cada categoría en un archivo de texto. Como ejemplo, usé categorías regulares, premium y diesel. Cada uno d...

5  Solicitud de Tkinter para administrar las tareas escolares  ( Tkinter application to manage school tasks ) 
Soy un principiante en la programación de la OOP y me pregunto cuál es la mejor manera de poner todas las ventanas y funciones de una aplicación de ventana en...

5  Python - Juego de Quiz con Tkinter  ( Python quiz game with tkinter ) 
He hecho un pequeño juego de preguntas en Python. Esta fue mi primera experiencia en la programación de GUI en Python con Tkinter. En general, no tengo mucho ...

5  Calculadora de área y volumen  ( Area and volume calculator ) 
Soy un codificador para principiantes, haciéndolo únicamente por diversión, habiendo comenzado a codificar hace unos dos meses con Python. Tengo un punto de t...

5  Generando contraseñas simples y complejas  ( Generating simple and complex passwords ) 
Soy bastante nuevo en Python y me gustaría algunos consejos y críticas en mi estilo / código de formato y lo que puede organizarse mejor. Soy un poco inestabl...

2  Hacer una lista de la entrada del usuario - Seguimiento  ( Making a list from user input follow up ) 
He realizado los cambios que la gente ha sugerido de mi Pregunta previa . Quiero intentarlo y hacerlo aún más ordenado si es posible. ¿Qué puedo cambiar para...

3  Convertidor binario / decimal / hexagonal usando tkinter  ( Binary decimal hex converter using tkinter ) 
Debatí mucho tiempo y duro antes de publicar esta pregunta, y hice mucho experimentación. Simplemente no puedo resolver una "elegante", de manera concisa de h...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos