Python Forum
Display more than one button in GUI to display MPU6000 Sensor readings
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Display more than one button in GUI to display MPU6000 Sensor readings
#1
Hi, I have been working with the serial monitoring program. My laptop connected to Arduino with USB port and trying to receive the MPU6000 I2C module data.

I have made the GUI in which I am selecting the items from drop-down list, After that a button is displayed and by clicking on that button I am able to display the message in a message box, and while selecting the different option from drop-down list then a new button appears on UI and the previous button is also available,

How Can I display only a single button while selecting the choice?

Here is my code

import serial
import json
import tkinter
from tkinter import messagebox
from tkinter import *
import tkinter as ttk

root = ttk.Tk()
root.title("Read Sensor")

ard = serial.Serial('COM4', timeout=1); 

 
# Add a grid
mainframe = Frame(root)
mainframe.grid(column=0,row=0, sticky=(N,W,E,S) )
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
mainframe.pack(pady = 100, padx = 100)
 
# Create a Tkinter variable
tkvar = StringVar(root)
 
# Dictionary with options
baud = { '9600','119200','34800'}
tkvar.set('9600') # set the default option

#Pop Up desciption
popupMenu = OptionMenu(mainframe, tkvar, *baud)
Label(mainframe, text="Baudrate").grid(row = 1, column = 1)
popupMenu.grid(row = 2, column =1)

#baudrate functions
def dropCall(*args):
    value = tkvar.get()
    if value == '9600':
        key_96(value)
        
    elif value == '119200':
        key_119(value)
        
    elif value == '38400':
        key_348(value)

    else:
        key_96(value)
        
    B = ttk.Button(root, text =value, command = helloCallBack)
    B.pack()

#Link Function
tkvar.trace('w', dropCall)

    
#Serial Callback Functions
def helloCallBack():
    k = ard.readline().decode('ascii');
    if(len(k)>0):
        print (k);
        size = len(k);
        #print (k[0:size-2]);
        print (size);
        messagebox.showinfo('Message From Arduino',k[0:size-2]+'\n'+str(size))

#Key Functions
def key_96(val1):
    v1 = int(val1)
    ard.baudrate = v1
    print(v1)
    
def key_119(val2):
    v2 = int(val2)
    ard.baudrate = v2
    print(v2)

def key_348(val3):
    v3 = int(val3)
    ard.baudrate = v3
    print(v3)   
Reply
#2
if you are referring to the
B = ttk.Button(root, text =value, command = helloCallBack)
statement, you can destroy it before creating the next button,
if B:
    B.destroy()
You do have to place a B=None statement at the top of your code to eliminate a "B doesn't exist" error on the first pass through the function. Also you can use one function for the value and key function. Something like this but you will have to test it yourself
 def dropCall(*args):
    value = tkvar.get()
    ## using a dictionary instead of if statements
    ## to show how dictionaries are used
    baud_dict={9600:val1, 38400:val3, 119200:val2}
    if value in baud_dict:
        ard.baudrate = int(baud_dict[value])
Reply
#3
Hi, As you mentioned I optimize the code accordingly but I am still not able to destroy the button after the click, I guess I am not placing the option correctly please check out my code :

import serial
import json
import tkinter
from tkinter import messagebox
from tkinter import *
import tkinter as ttk
import serial.tools.list_ports

root = ttk.Tk()
root.title("Read Sensor")

ard = serial.Serial('COM4', timeout=1); 

# Add a grid
mainframe = Frame(root)
mainframe.grid(column=0,row=0, sticky=(N,W,E,S) )
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
mainframe.pack(pady = 100, padx = 100)
 
# Create a Tkinter variable
tkvar = StringVar(root)
 
# Dictionary with options
baud = { '9600','119200','34800'}
tkvar.set('9600') # set the default option

#Pop Up desciption
popupMenu = OptionMenu(mainframe, tkvar, *baud)
Label(mainframe, text="Baudrate").grid(row = 1, column = 1)
popupMenu.grid(row = 2, column =1)

#baudrate functions
def dropCall(*args):
   B = None
   value = tkvar.get()
   ## using a dictionary instead of if statements
   ## to show how dictionaries are used
   baud_dict={'9600':value, '34800':value, '119200':value}
   if value in baud_dict:
       ard.baudrate = int(baud_dict[value])
       if B:
           B.destroy()
       B = ttk.Button(root, text =value, command = helloCallBack)
       B.pack()   
    
#Link Function
tkvar.trace('w', dropCall)

    
#Serial Callback Functions
def helloCallBack():
    k = ard.readline().decode('ascii');
    if(len(k)>0):
        print (k);
        size = len(k);
        #print (k[0:size-2]);
        print (size);
        messagebox.showinfo('Message From Arduino',k[0:size-2]+'\n'+str(size))
Reply
#4
Place the B=None statement at the top of your code, not in the function. This should work

root = ttk.Tk()
root.title("Read Sensor")
B=None 
Reply
#5
Hi barry76

Please try out the following modified script:
from functools import partial
import json
import serial
import tkinter as tk
from tkinter import messagebox

APP_TITLE = "Read Sensor"

APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 150
APP_HEIGHT = 150


class Application(object):
    PORT = "COM4" #For Linux try "/dev/ttyUSB0" 
    BAUDRATES = ['9600','119200','34800']
    
    def __init__(self, main_win):
        self.main_win = main_win
        
        try:
            port = self.PORT
            self.ard = serial.Serial(port, timeout=1); 
        except serial.serialutil.SerialException as err:
            print(err) #"Could not find port!:{}".format(err)) #port))
            messagebox.showinfo('Error Message', err)
            return
            
        self.build()
        
    def build(self):
        self.main_frame = tk.Frame(self.main_win)
        self.main_frame.pack(fill='both', expand=True)

        self.tkvar = tk.StringVar()
        #Set the default option (Baudrate)
        self.tkvar.set(self.BAUDRATES[0])
        self.tkvar.trace('w', self.drop_call)
        
        popup_menu_frame = tk.Frame(self.main_frame)
        popup_menu_frame.pack(expand=True)
        
        #Pop Up desciption
        tk.Label(popup_menu_frame, text="Baudrate", font='bold'
            ).grid(row=0, column=0)
        popupMenu = tk.OptionMenu(popup_menu_frame, self.tkvar, *self.BAUDRATES)
        popupMenu.grid(row=1, column=0)

        self.value_button_var = tk.StringVar(self.main_win, "None")
        tk.Button(self.main_frame, textvariable=self.value_button_var,
            command=self.hello_callback).pack(expand=True)

    def drop_call(self, *args):
        baudrate = self.tkvar.get()
        
        if baudrate == '9600':
            self.set_serial_baudrate(baudrate)
        elif baudrate == '119200':
            self.set_serial_baudrate(baudrate)
        elif baudrate == '38400':
            self.set_serial_baudrate(baudrate)
        else:
            self.set_serial_baudrate(self.BAUDRATES[0])
             
    #Serial Callback Functions
    def hello_callback(self):
        k = self.ard.readline().decode('ascii');
        if(len(k)>0):
            print (k);
            size = len(k);
            #print (k[0:size-2]);
            print (size);
            messagebox.showinfo(
                'Message From Arduino',k[0:size-2]+'\n'+str(size))
            
    def set_serial_baudrate(self, baudrate):
        print("Baudrate: {}".format(baudrate))
        self.value_button_var.set(baudrate)
        baud = int(baudrate)
        self.ard.baudrate = baud
        

def main():
    main_win = tk.Tk()
    main_win.title(APP_TITLE)
    #main_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    main_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    
    app = Application(main_win)
    
    main_win.mainloop()
 
 
if __name__ == '__main__':
    main()      
Greetings from wuf Wink
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] PyQt5 window closing when trying to display a graph bianca 4 1,621 Aug-12-2023, 03:25 PM
Last Post: bianca
  [PyQt] [solved] How to display a pdf-file in a PyQt6 widget BigMan 13 15,676 May-06-2023, 09:27 AM
Last Post: Axel_Erfurt
  [PyQt] [Solved]Display PyQtTable results from A->Z & Z->A Extra 2 1,142 Jul-18-2022, 04:04 PM
Last Post: Extra
  [PyQt] [Solved]Display Search Results in QTable Extra 5 2,387 Jun-29-2022, 10:20 PM
Last Post: Extra
  [PyQt] Cannot Display Image after Selecting Image bintangkecil 4 2,501 Jun-12-2022, 08:18 AM
Last Post: Axel_Erfurt
  looking for scripts that do simple image display Skaperen 10 4,133 Sep-13-2021, 05:35 PM
Last Post: FullOfHelp
  [PyQt] How do I display the DB table I will choose from the QComboBox in QTableWidget JokerSob 2 2,271 Aug-05-2021, 03:00 PM
Last Post: JokerSob
  Scaling text QLabel following display mode windows '100%, 125% ...) VIGNEAUD 2 2,217 Jul-07-2021, 06:38 PM
Last Post: deanhystad
  [Tkinter] How display matrix on canvas eedenj 9 8,808 Mar-17-2021, 03:58 PM
Last Post: eedenj
  [Tkinter] Display IP address in listbox dominicrsa 2 2,128 Oct-21-2020, 01:00 PM
Last Post: dominicrsa

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020