0

I want to pass the value of connected_complete from main.py to tkinter_oop.py. However, as I do like below code, the error

File "C:\Users\ching\OneDrive\Desktop\final_dobot_package\pydobot\tkinter_oop.py", line 17, in __init__
    self.button_connecting_signal  =  main_dobot.dobot_automation.connected_complete()
AttributeError: type object 'dobot_automation' has no attribute 'connected_complete'

Below is the part that passing value appeared:

Class graphic in tkinter_oop.py

import tkinter as tk
from tkinter import ttk 
import main_dobot 

class graphic(tk.Tk , main_dobot.dobot_automation):
    def __init__(self):
        super().__init__()
        self.button_connecting_signal  =  main_dobot.dobot_automation.connected_complete
 

    def button_connected_clicked(self): 
        main_dobot.dobot_automation()
        self.connecting = tk.Label(self.tab_2,text = "N/A", font=("Inter", 25))
        self.connecting.place(x = 500  , y = 350)
        if  self.button_connecting_signal  ==  1 :
            self.connecting.config("Connected")
        elif  self.button_connecting_signal== 2 :
            self.connecting.config("Not Connected")

main_dobot.py

from serial.tools import list_ports

import pydobot
from pydobot.enums import PTPMode
from pydobot.enums import jogMode

class dobot_automation : 
    def __init__(self,connected_complete = 0 ):
        self.connected_complete = connected_complete 
        self.available_ports = list_ports.comports()
        print(f'available ports: {[x.device for x in self.available_ports]}')
        
        if len(self.available_ports) == 0:
            print('No port avaliable')
            print ('Please Check Connection')
            self.connected_complete = 2
        else:
            self.port = self.available_ports[0].device
            self.device = pydobot.Dobot(port=self.port, verbose=True) 
            self.connected_complete = 1
     

Full code :

main.py

from serial.tools import list_ports

import pydobot
from pydobot.enums import PTPMode
from pydobot.enums import jogMode

class dobot_automation : 
    def __init__(self,connected_complete = 0 ):
        self.connected_complete = connected_complete 
        self.available_ports = list_ports.comports()
        print(f'available ports: {[x.device for x in self.available_ports]}')
        
        if len(self.available_ports) == 0:
            print('No port avaliable')
            print ('Please Check Connection')
            self.connected_complete = 2
        else:
            self.port = self.available_ports[0].device
            self.device = pydobot.Dobot(port=self.port, verbose=True) 
            self.connected_complete = 1
     
    def home_cabliration(self):
        if self.home_cablibration_command == 1: 
            self.device._set_queued_cmd_clear()
            self.device.set_jog_command( 1, jogMode.BP_DOWN, wait=True)
            self.device.wait(100)
            self.device.set_jog_command( 1, jogMode.IDLE , wait=True)
            self.device.wait(1000)
            self.device.set_home_params(178.9299, 3.3897 , -33.8784 , -82.7707, False)
            self.device.set_home_command (1,False)
            self.device.wait(1000)
            self.home_cablibration_command = 0 

    def cleaning_automation_process(self,automation_command):
        if automation_command == 1:
            self.device._set_queued_cmd_clear()

            #initial position 
            self.intial_moving_pos()

            #set 1 
            self.set_one_pos_up()
            self.open_grip()

            self.set_one__pos_down()
            #close grip
            self.close_grip() 
            #move up 
            self.set_one_pos_up()

            self.bath_one_pos_1_up()
            self.bath_one_pos_1_down()
            self.open_grip()
            self.bath_one_pos_1_up()
            self.close_grip() 
            self.disable_grip()


            #back to intial pos 
            self.intial_moving_pos()
            self.set_two_pos_up()
            self.open_grip()
            self.set_two_pos_down()
            #close grip
            self.close_grip() 
            #move up 
            self.set_two_pos_up()
            self.bath_one_pos_2_up()
            self.bath_one_pos_2_down()
            self.open_grip()
            self.bath_one_pos_2_up()
            self.close_grip() 
            self.disable_grip()

        
            #back to intial pos 
            self.intial_moving_pos()
            self.bath_one_pos_1_up()
            self.open_grip()
            self.bath_one_pos_1_down()
            self.close_grip() 
            self.bath_one_pos_1_up()
            self.set_one_pos_up()
            self.set_one__pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip() 

            self.intial_moving_pos()
            self.bath_one_pos_2_up()
            self.open_grip()
            self.bath_one_pos_2_down()
            self.close_grip() 
            self.bath_one_pos_2_up()
            self.set_two_pos_up()
            self.set_two_pos_down()
            self.open_grip()
            self.set_one_pos_up()
            self.close_grip() 
            (x, y, z, r, j1, j2, j3, j4) = self.device.pose()
            print(f'x:{x} y:{y} z:{z} r:{r} j1:{j1} j2:{j2} j3:{j3} j4:{j4}')
            automation_command = 0 
            

    def quit_automation_program(self) : 
        if self.quit_command == 1 :
            self.device.close()
            self.connected_complete = 2 
            self.quit_command = 0 
    
    def automation_emergency_stop(self ):
        if self.emmergency_command_stop == 1:
            self.device._set_queued_cmd_stop_exec()
            self.emmergency_command_stop = 0



    def intial_moving_pos(self): 
        self.device.move_to( 17.8941 , 6.0331 ,  0.5921 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_one_pos_up(self):
        self.device.move_to( 62.9159 , 13.689 , -10.0889 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
  
    def set_one__pos_down(self): 
        self.device.move_to( 62.8941 , 16.9492 , 28.2911 , 124.8797 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_up (self):
        self.device.move_to( 80.2371 , 6.9371 , -12.9820 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_two_pos_down(self): 
        self.device.move_to( 80.2371 , 6.9371 , 26.238 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def set_three_pos(self):
        self.device.move_to( 50.82 , -3.56 , -9.18 , -134.5598, PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        #device.move_to( 52.29 , 31.8271 , 13.82 , -85.6, PTPMode.MOVJ_ANGLE, wait=True)
        #device.wait(1000)
    def open_grip(self):  
        self.device.grip(False)
        self.device_setupdevice.wait(1000)
        self.device.suck(False)
        self.device.wait(1000)
    def close_grip(self):    
        self.device.grip(True)
        self.device.wait(1000)
        self.device.suck(True)
        self.device.wait(1000)
    def disable_grip(self): 
        self.device.suck(False)
        self.device.wait(1000)
    def bath_one_pos_1_up(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 ,-68.4760  , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)    
    def bath_one_pos_1_down(self):
        self.device.move_to( 3.1442 , 36.3588 , -14.6246 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to( 3.1442 , 36.3588 , 20.5754 , 89.4437 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_up(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , 99.4637 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
    def bath_one_pos_2_down(self):
        self.device.move_to ( 22.6588 , 46.7398 , -8.1826 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)
        self.device.move_to ( 22.6588 , 46.7398 , 16.3267 , -102.1199 , PTPMode.MOVJ_ANGLE, wait=True)
        self.device.wait(1000)



def dobot_main_run(home_cablibrate_command , automation_command,emergency_stop_command,quit_command): 
    dobot_arm = dobot_automation (home_cablibrate_command , automation_command,emergency_stop_command,quit_command)
    try:
        while (1):
            dobot_arm.serial_port_connecting ()
            dobot_arm.home_cabliration()
            dobot_arm.cleaning_automation_process()
            dobot_arm.automation_emergency_stop()
            dobot_arm.quit_automation_program()
    except:
        print ("There is error in the program , please stop the program immediately ")


tkinter_oop.py


import tkinter as tk
from tkinter import ttk 
import main_dobot 


class graphic(tk.Tk , main_dobot.dobot_automation):
    def __init__(self):
        super().__init__()
       
        self.reset_clock = 0
        self.check_value = 0 
        self.done = 0
        self.minute = 1 
        self.second = 0   
        
        #button value 
        self.button_connecting_signal  =  main_dobot.dobot_automation.connected_complete
        self.button_home_cablirate_done = 0
        self.button_automation_cablirate_done = 0 
        self.button_quit_done = 0
        self.emergency_stop_done = 0   


        
        self.title('Automation Cleaning Process')
        self.geometry('1100x800+100+100')
        self.resizable(False, False)
        self.menubar = tk.Menu(self)
        filemenu = tk.Menu(self.menubar, tearoff=0)
        filemenu.add_command(label="New")
        filemenu.add_command(label="Open")
        filemenu.add_command(label="Save")
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=self.quit)
        self.menubar.add_cascade(label="File", menu=filemenu)
        
        helpmenu = tk.Menu(self.menubar, tearoff=0)
        helpmenu.add_command(label="Help Index")
        helpmenu.add_command(label="About...")
        self.menubar.add_cascade(label="Help",menu=helpmenu)

        #self.integer_variable_x_value = tk.IntVar()
        #self.integer_variable_y_value = tk.IntVar()
        #self.integer_variable_z_value = tk.IntVar() 
        #self.integer_variable_r_value = tk.IntVar() 
        #self.integer_variable_x_value.set(0)
        #self.integer_variable_y_value.set(0)
        #self.integer_variable_z_value.set(0)
        #self.integer_variable_r_value.set(0) 
        
        self.tabControl = ttk.Notebook(self) 
        self.tab_1 = ttk.Frame(self.tabControl)
        self.tab_2 = ttk.Frame(self.tabControl)
        self.tabControl.add(self.tab_2,text = 'HOME')
        self.tabControl.add(self.tab_1,text = 'Option')
        self.tabControl.pack(expand = 1, fill ="both")
        
        self.set_button()
       
        self.set_text_gui()
       
        self.set_timer_counter_process(self.minute,self.second)
        #self.update_output(200,300,400,500)
        self.config(menu=self.menubar)

       







    def set_button(self):
        self.button_home_cablirate = tk.Button (self.tab_1,text = "Home Cabliration", command = self.button_home_cablirate_clicked, width = 50 , height = 5 ) 
        self.button_home_cablirate.place(x=380,y=150)
        self.button_Automation_Process = tk.Button(self.tab_1, text='Automation Process',command=self.button_automation_clicked_clock_counting_down, width = 50 , height = 5)
        self.button_Automation_Process.place(x=380,y=300)
        self.button_Stop = tk.Button(self.tab_1, text='Stop',command=self.button_quit_clicked, width = 50 , height = 5 )
        self.button_Stop.place(x=380,y=450)
        self.button_connected = tk.Button (self.tab_2,text = "Connecting Dobot" , command=self.button_connected_clicked, width=50 , height =5 )
        self.button_connected.place(x=400,y=400)
        self.emergency_button = tk.Button(self, text='Emergency Stop ',command=self.button_emergency_stop, width = 25 , height = 8 )
        self.emergency_button.place(x= 900,y = 50)
        self.slot_1 =  tk.Button(self.tab_2, text='2',command=self.two_slot_selected, width = 20 , height = 4)
        self.slot_1.place(x= 100 ,y = 250 )
        self.slot_2 =  tk.Button(self.tab_2, text='4',command=self.four_slot_selected, width = 20 , height = 4)
        self.slot_2.place(x= 500,y = 250)
        self.slot_3 =  tk.Button(self.tab_2, text='6',command=self.sixth_slot_selected, width = 20 , height = 4)
        self.slot_3.place(x= 850 ,y = 250)
        
        


    def button_connected_clicked(self): 
        main_dobot.dobot_automation()
        self.connecting = tk.Label(self.tab_2,text = "N/A", font=("Inter", 25))
        self.connecting.place(x = 500  , y = 350)
        if  self.button_connecting_signal  ==  1 :
            self.connecting.config("Connected")
        elif  self.button_connecting_signal== 2 :
            self.connecting.config("Not Connected")
            
     
     

 

    def button_home_cablirate_clicked(self): 
      print ("button home cablirate click ")
      self.button_home_cablirate_done  = 1
      
     
     
   
    def button_automation_clicked_clock_counting_down(self):
     self.done = 1 
     self.button_automation_cablirate_done = 1 
     print ("button automation click ")
     

    def button_quit_clicked(self): 
     self.button_quit_done = 1
     print ("button quit click")
     

    def button_emergency_stop (self):
        self.emergency_stop_done  = 1
        print ("button emergency clicked")


    def two_slot_selected (): 
        pass


    def four_slot_selected (): 
        pass

    def sixth_slot_selected () :
        pass


    def set_text_gui(self): 
        #declare label 
        self.choose_clean_slot = tk.Label(self.tab_2,text = "Please choose how many slot avaliable ", font=("Inter", 20))

        self.time_title = tk.Label(self.tab_2, text = "Time Process:", font=("Inter",30))
        self.time_colon= tk.Label(self.tab_2, text = ":", font=("Inter",  30))
        self.min_label= tk.Label(self.tab_2, text = "min", font=("Inter", 30))
        self.second_label=tk.Label(self.tab_2, text = "sec", font=("Inter",30))
        self.label_minute = tk.Label(self.tab_2,font=("Inter",30))
        self.label_second = tk.Label (self.tab_2,font=("Inter",30))
        self.label_minute_zero_add = tk.Label(self.tab_2,font=("Inter",30))
        self.label_second_zero_add = tk.Label(self.tab_2,font=("Inter",30))
        # position label 
        
        self.choose_clean_slot.place(x = 85  , y = 100)


        self.time_title.place(x=85,y=590) 
        self.time_colon.place(x =230,y=650)
        self.min_label.place(x=150,y=650)
        self.second_label.place(x=335,y=650)
        self.label_minute.place(x = 120 , y = 650)
        self.label_second.place(x=  278 , y = 650)
        self.label_minute_zero_add.place(x=  90 ,y=650)
        self.label_second_zero_add.place(x = 250 ,y= 650)
   
    #def update_output(self , input_dobot_x, input_dobot_y, input_dobot_z , input_dobot_r):
        # update x-axis 
        #self.integer_variable_x_value.set(input_dobot_x)
        #self.x_axis_value.config(text=str(self.integer_variable_x_value.get()))
        # update y axis 
        #self.integer_variable_y_value.set(input_dobot_y)
        #self.y_axis_value.config(text=str(self.integer_variable_y_value.get()))
        # update z axis 
        #self.integer_variable_z_value.set(input_dobot_z)
        #self.z_axis_value.config(text=str(self.integer_variable_z_value.get()))
        
        # update r axis
        #self.integer_variable_r_value.set(input_dobot_r)
        #self.r_axis_value.config(text=str(self.integer_variable_r_value.get()))
        
        #update all the variable every 100secs to GUI 
        #self.after(100,self.update)

    def set_timer_counter_process(self,minute,second):
        self.label_minute['text'] = minute
        self.label_second['text'] = second
        check_minute_length = len(str(minute))
        check_second_length = len(str(second))
        if check_minute_length == 1: 
            self.label_minute_zero_add['text'] = 0 
        else: 
            self.label_minute_zero_add['text'] =''

        if check_second_length == 1:
            self.label_second_zero_add['text'] = 0  
        else:
            self.label_second_zero_add['text'] ='' 

        if self.done == 1:      
            if second  > 0 :
                second = second - 1       
            elif second <= 0 :
                if minute > 0:
                    minute  = minute - 1  
                    second  = 60 
                else:
                    self.done = 0
        else:
            minute = 1
            second = 0           
        self.after(1000, self.set_timer_counter_process, minute , second) 


def run_GUI():
    
    User_graphic = graphic()
    User_graphic.mainloop()


run_GUI()



7
  • 3
    Please include a Minimal, Reproducible Example. Commented Jan 4, 2023 at 23:36
  • 1
    The assignment self.button_connecting_signal = main_dobot.dobot_automation.connected_complete tries to access .complete on the class main_dobot.dobot_automation.connected, but only an instance of that class would have the attribute. Commented Jan 4, 2023 at 23:42
  • connected_complete is an instance attribute, not a class attribute. You need to create an instance of main_dobot.dobot_automation and use that. Commented Jan 4, 2023 at 23:42
  • @Barmar is graphic not an instance of main_dobot.dobot_automation though? Commented Jan 4, 2023 at 23:49
  • @PeterWood once you instantiate the class with graphic() (you should really capitalise class names), the result will be an instance of main_dobot.dobot_automation as well, but graphic itself is a class, not an instance. You're likely confusing the type (class) and the value (instance). Commented Jan 4, 2023 at 23:59

1 Answer 1

2

It seems you're confusing classes and instances.

Consider this simple example:

class Fruit:
    ...


class Apple(Fruit):
    ...


my_snack = Apple()

After executing the above, my_snack is an instance of Apple, and through inheritance also an instance of Fruit. Both Fruit and Apple are classes (hence the spelling with a capital, although that's a convention and not a rule - treat it as a rule for readable code).

You have this:

class dobot_automation():
    def __init__(self):
        self.connected_complete = 'some value'


class graphic(dobot_automation):
    def __init__(self):
        self.button_connecting_signal = dobot_automation.connected_complete



my_g = graphic()

Here, you're trying to make my_g an instance of graphic (see how capitalising would make that easier to understand?). However, instantiating the class calls the __init__ and that tries to access dobot_automation.connected_complete.

There, dobot_automation is a class, and there is no class attribute connected_complete defined on the class, only an instance attribute when the class is instanced.

So, although this is probably not what you want, this would work:

class DobotAutomation():
    def __init__(self):
        self.connected_complete = 'some value'


class Graphic(DobotAutomation):
    def __init__(self):
        super().__init__()
        self.button_connecting_signal = self.connected_complete



my_g = Graphic()

By calling the __init__ of the superclass first, the attribute is available on self, and can be referenced.

The reason you likely don't want that is that this just assigns the value of .connected_complete to .button_connecting_signal and depending on whether that value is mutable, you may just be creating extra copies of a value (an int in your case).

If you just want button_connecting_signal to act as an alias for connected_complete, you can do this:

class Graphic(DobotAutomation):
    def __init__(self):
        ...
        
    @property
    def button_connecting_signal(self):
        return self.connected_complete  # after all, this is a DobotAutomation as well

For completeness, a class attribute is defined like this:

class Fruit:
    typical_calories = 90


class Apple(Fruit):
    def __init__(self):
        self.calories = self.typical_calories + 5


my_snack = Apple()
print(my_snack.calories)  # prints 95

Note that this would also work in the constructor for Apple:

        self.calories = Fruit.typical_calories + 5

But that takes .typical_calories directly from the class Fruit, not from whatever ancestor Apple may have inbetween (which might redefine that value).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.