0

I have created a TKinter application that calculates the offsets and ratios that map robot plane to camera cordinate in pixels. I have several features that require the control of the robot via tkinter buttons. The app is done and working but trying to stop the worry of spamming a button, and the robot moving for another 15 seconds because it is executing each click. This is my attempt at having tkinter not execute all the presses.

my custom image button:

class ImageButton(ctk.CTkButton):
    def __init__(self, parent, text,function, col, row, image, padx, pady, width, color = 'dark-gray'):
        super().__init__(
            master = parent, 
            text  = text,
            command= function,
            image = image,
            fg_color= MINT,
            hover_color = DARK_BLUE,
            text_color = LIGHT_BLUE,
            width = width
        )
        self.grid(column = col, row = row, sticky = 'NSEW', pady =pady, padx = padx)

and my robot class with layout and junk deleted:

import math
import os
import sys
import customtkinter as ctk
import tkinter as tk
from tkinter import *

import numpy as np
from settings import *
from PIL import Image
import cv2 as cv
class MoveRobotWelcome(ctk.CTkFrame):
    
    def __init__(self, parent, controller, frame, robot = None):
        ctk.CTkFrame.__init__(self, parent)
        self.robot = robot
        self.gripperOpen = True
        self.increment = tk.DoubleVar()
        self.increment.set(0.001)  # Default value

        self.roll = 180
        self.pitch = -.0001
        self.yaw = 30

        self.buttons = []

        #self.robot = Robot()
        

        Pximage = Image.open(r'increase_x.png')
        Nximage = Image.open(r'decrease_x.png')
        Pyimage = Image.open(r'increase_y.png')
        Nyimage = Image.open(r'decrease_y.png')
        Przimage = Image.open(r'increase_rz.png')
        Nrzimage = Image.open(r'decrease_rz.png')
        Pzimage = Image.open(r'increase_z.png')
        Nzimage = Image.open(r'decrease_z.png')
        grip_image = Image.open(r'gripper.png')
        

        Px = ImageButton(controller_frame, text = '', function = self.move_pos_x, col = 1, row = 0, image = Pxinvert_image, padx=10, pady=10, width = 40)
        Nx = ImageButton(controller_frame, text = '', function = self.move_neg_x, col = 1, row = 1, image = Nxinvert_image, padx=10, pady=10, width = 40)
        Py = ImageButton(controller_frame, text = '', function = self.move_pos_y, col = 1, row = 2, image = Pyinvert_image, padx=10, pady=10, width = 40)
        Ny = ImageButton(controller_frame, text = '', function = self.move_neg_y, col = 1, row = 3, image = Nyinvert_image, padx=10, pady=10, width = 40)
        Pz  = ImageButton(controller_frame, text = '', function = self.move_pos_z, col = 1, row = 4, image = Pzinvert_image, padx=10, pady=10, width = 40)
        Nz  = ImageButton(controller_frame, text = '', function = self.move_neg_z, col = 1, row = 5, image = Nzinvert_image, padx=10, pady=10, width = 40)
        Prz  = ImageButton(controller_frame, text = '', function = self.move_pos_rz, col = 1, row = 6, image = Przinvert_image, padx=10, pady=10, width = 40)
        Nrz  = ImageButton(controller_frame, text = '', function = self.move_neg_rz, col = 1, row = 7, image = Nrzinvert_image, padx=10, pady=10, width = 40)
        gripper = ImageButton(controller_frame, text = '', function = self.toggle_gripper, col = 1, row = 8, image = grip_invert_image, padx=10, pady=10, width = 40)
        
        self.buttons.append(Px)
        self.buttons.append(Nx)
        self.buttons.append(Py)
        self.buttons.append(Ny)
        self.buttons.append(Pz)
        self.buttons.append(Nz)
        self.buttons.append(Prz)
        self.buttons.append(Nrz)
        self.buttons.append(gripper)

        Px_label= ctk.CTkLabel(controller_frame, text = "+ X", text_color= DARK_BLUE)
        Nx_label= ctk.CTkLabel(controller_frame, text = "- X", text_color= DARK_BLUE)
        Py_label= ctk.CTkLabel(controller_frame, text = "+ Y", text_color= DARK_BLUE)
        Ny_label= ctk.CTkLabel(controller_frame, text = "- Y", text_color= DARK_BLUE)
        Prz_label= ctk.CTkLabel(controller_frame, text = "+ Z", text_color= DARK_BLUE)
        Nry_label= ctk.CTkLabel(controller_frame, text = "- Z", text_color= DARK_BLUE)
        gripper_label= ctk.CTkLabel(controller_frame, text = "Toggle Gripper : ", text_color= DARK_BLUE)
        Pz_label= ctk.CTkLabel(controller_frame, text = "+ Rz", text_color= DARK_BLUE)
        Nz_label= ctk.CTkLabel(controller_frame, text = "- Rz", text_color= DARK_BLUE)


        Px_label.grid(row = 0, column = 0)
        Nx_label.grid(row = 1,column = 0)
        Py_label.grid(row = 2,column = 0)
        Ny_label.grid(row = 3,column = 0)
        Prz_label.grid(row = 4,column = 0)
        Nry_label.grid(row = 5,column = 0)
        gripper_label.grid(row = 8,column = 0)
        Pz_label.grid(row = 6,column = 0)
        Nz_label.grid(row = 7,column = 0)

        radio_frame = ctk.CTkFrame(main_frame, fg_color = MINT)
        radio_frame.grid(row = 0, column = 1, columnspan = 2, sticky = 's', pady = (20,10))
        for i in range(0, 4):
            radio_frame.grid_rowconfigure(i, weight = 1)

        radio_frame.grid_rowconfigure(1, weight = 1)
        self.radio1 = ctk.CTkRadioButton(radio_frame, text="0.001", variable=self.increment, value=0.001, command=self.update_increment, text_color=DARK_BLUE, border_color = DARK_BLUE, fg_color = LIGHT_BLUE)
        self.radio2 = ctk.CTkRadioButton(radio_frame, text="0.01 ", variable=self.increment, value=0.01, command=self.update_increment, text_color=DARK_BLUE, border_color = DARK_BLUE, fg_color = LIGHT_BLUE)
        self.radio3 = ctk.CTkRadioButton(radio_frame, text="0.05 ", variable=self.increment, value=0.05, command=self.update_increment, text_color=DARK_BLUE, border_color = DARK_BLUE, fg_color = LIGHT_BLUE)

    def disable_buttons(self):
        for button in self.buttons:
            button.configure(state=DISABLED)

    def enable_buttons(self):
        for button in self.buttons:
            button.configure(state=NORMAL)

    def update_increment(self):
        # Update the label to show the current increment
        self.label.configure(text=f"Current Increment: {self.increment.get()}")

    def move_pos_x(self):
        self.disable_buttons()

        try:
            actual_tcp_pose = self.robot.rtde_r.getActualTCPPose()

            rrx = math.radians(self.roll)
            rry = math.radians(self.pitch)
            rrz = math.radians(self.yaw)
            rpx, rpy, rpz = self.robot.rpy2rv(rrx, rry, rrz)

            actual_tcp_pose[3] = rpx
            actual_tcp_pose[4] = rpy
            actual_tcp_pose[5] = rpz

            actual_tcp_pose[0] += self.increment.get()

            self.robot.moveL(actual_tcp_pose, .1, .1)
        finally:
            self.enable_buttons()

    def move_pos_y(self):
        self.disable_buttons()

        try:
            actual_tcp_pose = self.robot.rtde_r.getActualTCPPose()
 
            rrx = math.radians(self.roll)
            rry = math.radians(self.pitch)
            rrz = math.radians(self.yaw)
            rpx, rpy, rpz = self.robot.rpy2rv(rrx, rry, rrz)

            actual_tcp_pose[3] = rpx
            actual_tcp_pose[4] = rpy
            actual_tcp_pose[5] = rpz

            actual_tcp_pose[1] += self.increment.get()
 
            self.robot.moveL(actual_tcp_pose, .1, .1)
        finally:
            self.enable_buttons()

Setting the state to disabled for each button on my page so that while robot is executing move after first click other/extra button presses aren't registered/queued

2
  • During the periods when your buttons are disabled - there is no handling of events going on (the mainloop is not running), so there is no opportunity for the unwanted clicks to be discarded. You need to somehow return to the mainloop while the robot movements are being processed - either by chaining their steps together using .after(), or running them in a separate thread - so that the disabling of the buttons actually does something. Commented Jul 8 at 20:35
  • Try calling self.update() at the end of disable_buttons() and enable_buttons().
    – acw1668
    Commented Jul 9 at 7:39

0

Browse other questions tagged or ask your own question.