Search code examples
pythonsocketstkinterttk

How to send a signal to run a function one folder up in Python, maybe even with Tkinter library


Trying to create a simple program where one desktop receives a message from a client from another desktop and changes the color of the background. The problem is that I am not sure how to go about sending the signal to change the background. I was thinking about an easy event system, though couldn't figure it out or introducing a global variable, but couldn't figure out how to bind it with the changing background.

Code for the desktop, where the background should change:

from tkinter import *
from tkinter import ttk
import random
from Sockets import SocketServer

def change_color():
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    
    color = '#%02x%02x%02x' % (r, g, b)
    
    root.config(bg=color)

root = Tk() # should run the function above after connecting with the client 
frame = ttk.Frame(root, padding=100).grid()

root.mainloop()

Code for the server socket:

import socket # TODO: server should run only when the desktop is booted up, on exit the server should be terminated

S = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET, SOCK_STREAM - constants, represent adress families and represent the socket types respectively
HOST = socket.gethostname()
PORT = 65432

class ServerSide:        
    def __init__(self):
        S.bind((HOST, PORT)) # binds the socket with the address, requests tuple type
        print("Binded with", HOST, PORT, "\n Awaiting connection...")
        S.listen(1) # listens until a limit of connections has been reached # FIXME: maybe add another listening faction if a client is terminated, so the server can accept the next one
        
        self.con, self.addr = S.accept() # accept a connection
        print("Connected with", self.addr)

    def ActivateServer(self):
        while 1:
            data = server.con.recv(1024).decode() # recieves signal # FIXME: check whether less than 1024 can be supported
            if data == "e": # if an exit is signaled -> closes connection and server socket
                # FIXME: make it close both apps
                server.con.close() 
                S.close()
                print("Message from client:", data, "Connection and server were terminated.")
                break
            elif data == "ch":
                # FIXME: send the signal to 2nd desktop
                print("Message from client:", data, "Changed the background on 2nd desktop.")
                data = ""
        
server = ServerSide()
server.ActivateServer()

Any help would be appreciated, thanks!


Solution

  • One solution is that you can use a client-server architecture with sockets to establish communication between the two computers.

    Server Side (Desktop 1): Receives messages and changes the background color.

    from tkinter import *
    from tkinter import ttk
    import random
    import threading
    import socket
    
    def change_color():
        r = random.randint(0, 255)
        g = random.randint(0, 255)
        b = random.randint(0, 255)
        
        color = '#%02x%02x%02x' % (r, g, b)
        
        root.config(bg=color)
    
    def receive_messages():
        while True:
            data = server_socket.recv(1024).decode()
            if data == "exit":
                break
            elif data == "change_color":
                change_color()
    
    root = Tk()
    frame = ttk.Frame(root, padding=100)
    frame.grid()
    
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    host = socket.gethostname()
    port = 12345  # You can use a different port number
    server_socket.bind((host, port))
    server_socket.listen(1)
    print(f"Listening for connections on {host}:{port}")
    
    client_socket, addr = server_socket.accept()
    print(f"Connected to {addr}")
    
    message_thread = threading.Thread(target=receive_messages)
    message_thread.start()
    
    root.mainloop()
    

    Client Side (Desktop 2): Sends messages to change the background color.

    import socket
    
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    host = socket.gethostname()
    port = 12345  # Make sure it matches the port on the server side
    
    client_socket.connect((host, port))
    
    while True:
        message = input("Enter 'exit' to quit or 'change_color' to change the background color: ")
        client_socket.send(message.encode())
        if message == "exit":
            break
    
    client_socket.close()
    

    In this setup, you have a server (Desktop 1) that listens for incoming connections and messages. When it receives a "change_color" message, it changes the background color. The client (Desktop 2) connects to the server and sends messages to trigger actions.