I have a class called My_Buttons in button.py file. And I created object of the class in the same file in order to use in different files the same instance.
import math
from frontend.utilities.screen_info import screen_info
from frontend.env import BTN_SIZE, SUCCESS_COLOR, FAIL_COLOR, WARNING_COLOR, BTN_X_PADDING, \
BTN_Y_PADDING
from frontend.modules.master import master, Button
from backend.ip_list import ip_list
screen_width, screen_height = screen_info()
class MyButtons:
def __init__(self):
self.current_btn = None
self.btns = []
self.items = ip_list
self.attach_all_buttons()
def create_btn(self, item, k):
btn = Button(
master,
text=item,
bg=FAIL_COLOR,
command=lambda: self.click_btn(k)
)
self.btns.append(btn)
self.current_btn = btn
def click_btn(self, id):
if self.btns[id].cget('bg') == WARNING_COLOR:
self.btns[id].config(bg=SUCCESS_COLOR)
def update_btns(self, items):
for i, item in zip(range(len(self.btns)), items):
bg_color = SUCCESS_COLOR if item['is_alive'] == True else FAIL_COLOR
self.btns[i].config(bg=bg_color)
def configure_btn(self, col):
master.grid_columnconfigure(col, minsize=BTN_SIZE)
# btn.bind('<Enter>', lambda: btn.config(text='Mouse in'))
# btn.bind('<Leave>', lambda: btn.config(text='Mouse out'))
def attach_btn(self, row, col):
self.current_btn.grid(
row=row,
column=col,
padx=BTN_X_PADDING,
pady=BTN_Y_PADDING,
sticky='wens'
)
def attach_all_buttons(self):
items_count = len(self.items)
cols = math.floor(screen_width / BTN_SIZE)
rows = math.ceil(items_count / cols)
k = 0
for row in range(rows):
partial_items = self.items[row * cols:(row + 1) * cols]
for col, item in zip(range(cols), partial_items):
self.create_btn(item, k)
self.attach_btn(row, col)
self.configure_btn(col)
k = k + 1
my_button = MyButtons()
monitor.py file for creating screen:
from frontend.modules.master import master
def prepare_monitor():
master.mainloop()
prepare_monitor()
And main.py file with following code:
from frontend.modules.button import my_button
from frontend.client_socket import client_socket
import pickle
def start():
print('Monitor Network')
while True:
data = client_socket.client_socket.recv(4096)
client_socket.message = pickle.loads(data)
if client_socket.message:
my_button.update_btns(client_socket.message)
print('Server Socket data: ', client_socket.message)
client_socket.message = None
start()
In this project I want to update buttons on monitor based on backend data, and used sockets. Firstly, run monitor.py then main.py files.
But it is appearing all imports getting copy of the my_button object. I want to use the same instance is used in all imports. I am changing this object from different places. Any help would be greatly appreciated !
Firstly, run monitor.py then main.py files.
Apologies for the potentially simplistic answer, but if I understand the situation correctly, you're running two files separately. They import the same shared file, button.py
, but the values inside this shared file seem to be copies, and mutations are not propagated between the two executions.
If that's the case, it's how Python programs work: every time you execute python.exe
, all code is run anew. Your line my_button = MyButtons()
was executed twice, once for python monitor.py
and once for python main.py
, and they created different MyButtons
instances that share nothing between them.
If you really want them to share a value, you can use concurrency primitives like threads:
from threading import Thread
from time import sleep
my_shared_list = [0]
def loop_1():
while True:
my_shared_list.pop()
print(f"loop_1 - {my_shared_list=}")
sleep(0.5)
def loop_2():
while True:
my_shared_list.append(1)
print(f"loop_2 - {my_shared_list=}")
sleep(0.4)
Thread(target=loop_1).start()
loop_2()
# loop_1 - my_shared_list=[]
# loop_2 - my_shared_list=[1]
# loop_2 - my_shared_list=[1, 1]
# loop_1 - my_shared_list=[1]
# loop_2 - my_shared_list=[1, 1]
# loop_1 - my_shared_list=[1]
# loop_2 - my_shared_list=[1, 1]
# loop_1 - my_shared_list=[1]
# loop_2 - my_shared_list=[1, 1]
# loop_2 - my_shared_list=[1, 1, 1]
# loop_1 - my_shared_list=[1, 1]
# ...
This code runs two infinite loops in one script, loop_1
and loop_2
(similar to your prepare_monitor
and start
). The first one is run in a separate thread (Thread(target=loop_1).start()
), so now we have the main thread executing loop_2
, and the new thread executing loop_1
. They both access the same my_shared_list
, with one adding and other removing values from it.