1

GUI Window

with the given GUI, if enable/disable test is selected i want to launch a script with the given parameters of test name, ip address, send email.

processes={}

if (start_stop_checkbut1.get()):
    processes['192.168.x.xx'] = {
        'name': test_name_var1.get(),
        'ip': ip_var1.get(),
        'enable_disable': start_stop_checkbut1.get(),
        'email': eb1.get(),
        'email_address': email_address1.get()
        }
    call_main_script('192.168.x.xx', processes)

im fairly new to GUI programming so what im aiming to do here is whichever row of enable/disable is selected, a script can be launched with the parameters and i want them all to run simultaneously (can be run in multiple instances of command prompt too).

i am not sure how to achieve this, would i need to do multiprocessesing or subprocesses? if so, can i get some guidance in regards to that.

1 Answers1

0

You question is not really connected to Tkinter and GUI programming. You need multithreading or multiprocessing. The efficient solution depends on what you want to do. You can see the following pages about select the multithreading/multiprocessing: This and This

Honestly based on your question your problem is not crystal clear for me but I tried to do my best in my answer.

You can see a test code below, without any parallelism, so it's not the solution for you.

Code:

"""
Example script for data processing
"""


def call_main_script(ip_adr_str, processes_dict):
    """
    Print the data structure for testing.

    Args:
        ip_adr_str: The IP address as string to define the dict key.
        processes_dict: The dict data structure

    Returns: None

    """

    # Get the key-values based on the given IP address
    for key, value in processes_dict[ip_adr_str].items():
        print("{} -> {}".format(key, value))
    print("\n\n")


class DummyCheckBox:
    """
    A Dummy class for simulate the CheckBox widget of TK.
    """

    def __init__(self, number_of_box):
        """
        The constructor of DummyCheckBox

        Args:
            number_of_box: Input parameter of "widget"
        """

        self.number_of_box = number_of_box

    def get(self):
        """
        Provides some dummy value (Class name and the input value...).

        Returns: Dummy str.
        """

        return "{}_{}".format(self.__class__.__name__, self.number_of_box)


class DummyName:
    """
    A Dummy class for simulate the Input widget of TK.
    """

    def __init__(self, name_input):
        """
        The constructor of DummyName

        Args:
            name_input: Input parameter of "widget"
        """
        self.name = name_input

    def get(self):
        """
        Provides some dummy value (Class name and the input value...).

        Returns: Dummy str.
        """

        return "{}_{}".format(self.__class__.__name__, self.name)


# Creating the instances from the Check Box class.
dummy_check_box_1 = DummyCheckBox(1)
dummy_check_box_2 = DummyCheckBox(2)
dummy_check_box_3 = DummyCheckBox(3)

# Creating the instances from the Name widget class.
dummy_name_1 = DummyName("FOO")
dummy_name_2 = DummyName("BAR")
dummy_name_3 = DummyName("BAZ")

processes = {}

# Put the instances to lists.
check_boxes = [dummy_check_box_1, dummy_check_box_2, dummy_check_box_3]
names = [dummy_name_1, dummy_name_2, dummy_name_3]

# You can process the lists in ony for loop with the "zip" function.
for check_box, name in zip(check_boxes, names):
    if check_box.get():
        processes["192.168.x.xx"] = {
            "name": name.get(),
            "ip": "dummy_ip",
            "enable_disable": check_box.get(),
            "email": "dummy_mail",
            "email_address": "dummy_adress",
        }
        call_main_script("192.168.x.xx", processes)

Output:

>>> python3 test.py

name -> DummyName_FOO
ip -> dummy_ip
enable_disable -> DummyCheckBox_1
email -> dummy_mail
email_address -> dummy_adress

name -> DummyName_BAR
ip -> dummy_ip
enable_disable -> DummyCheckBox_2
email -> dummy_mail
email_address -> dummy_adress

name -> DummyName_BAZ
ip -> dummy_ip
enable_disable -> DummyCheckBox_3
email -> dummy_mail
email_address -> dummy_adress

The following example contains a multithreading solution. I have commented all changed place in the code.

Code:

"""
Example script for data processing
"""

import threading
import random
import time


def call_main_script(processes_dict):
    """
    Print the data structure for testing.

    Args:
        processes_dict: The dict data structure

    Returns: None

    """

    # Get a random integer between 1-5 and sleep it in secs.
    random_sleep = random.randint(1, 5)
    time.sleep(random_sleep)
    print(
        "[{}] ({} secs slept) name -> {}".format(
            threading.current_thread().name, random_sleep, processes_dict["name"]
        )
    )


class DummyCheckBox:
    """
    A Dummy class for simulate the CheckBox widget of TK.
    """

    def __init__(self, number_of_box):
        """
        The constructor of DummyCheckBox

        Args:
            number_of_box: Input parameter of "widget"
        """

        self.number_of_box = number_of_box

    def get(self):
        """
        Provides some dummy value (Class name and the input value...).

        Returns: Dummy str.
        """

        return "{}_{}".format(self.__class__.__name__, self.number_of_box)


class DummyName:
    """
    A Dummy class for simulate the Input widget of TK.
    """

    def __init__(self, name_input):
        """
        The constructor of DummyName

        Args:
            name_input: Input parameter of "widget"
        """
        self.name = name_input

    def get(self):
        """
        Provides some dummy value (Class name and the input value...).

        Returns: Dummy str.
        """

        return "{}_{}".format(self.__class__.__name__, self.name)


# Creating the instances from the Check Box class.
dummy_check_box_1 = DummyCheckBox(1)
dummy_check_box_2 = DummyCheckBox(2)
dummy_check_box_3 = DummyCheckBox(3)

# Creating the instances from the Name widget class.
dummy_name_1 = DummyName("FOO")
dummy_name_2 = DummyName("BAR")
dummy_name_3 = DummyName("BAZ")

# This list will contain the dict structures.
processes = []

# Put the instances to lists.
check_boxes = [dummy_check_box_1, dummy_check_box_2, dummy_check_box_3]
names = [dummy_name_1, dummy_name_2, dummy_name_3]

# You can process the lists in ony for loop with the "zip" function.
for check_box, name in zip(check_boxes, names):
    if check_box.get():
        # Creating the dict data structure.
        data_structure = {
            "name": name.get(),
            "ip": "dummy_ip",
            "enable_disable": check_box.get(),
            "email": "dummy_mail",
            "email_address": "dummy_adress",
        }

        # Append the actual dict data structure to the process list.
        processes.append(data_structure)

# Creating the list for the started threads. We will wait the threads based on this list.
threads = []

# Creating threads for the dict data structures.
for single_dict in processes:
    # Creating the thread which calls the "call_main_script" function with "single_dict" argument.
    t = threading.Thread(target=call_main_script, args=(single_dict,))
    # Start the actual thread.
    t.start()
    # Append the Thread object to the list.
    threads.append(t)

# Join (Stop) the Threads one-by-one.
for t in threads:
    # Wait until thread is completely executed
    t.join()

print("Done!")

Output:

>>> python3 test.py

[Thread-3] (1 secs slept) name -> DummyName_BAZ
[Thread-1] (2 secs slept) name -> DummyName_FOO
[Thread-2] (5 secs slept) name -> DummyName_BAR
Done!

As you can see on above output section the 3 different dict data structures started on 3 threads. I have added a random (1-5 secs) sleep for better representation.

milanbalazs
  • 4,811
  • 4
  • 23
  • 45
  • Hi there, apologies for the unclear problem i wasnt quite sure how to word it. I want to use the GUI to launch multiple instances of a script with different parameters each time. however, your solution of multithreading seems to work to an extent and i am working towards making it work more effectively. thank you – Tawseef Patel Jun 29 '22 at 17:37
  • You are welcome! I hope my answer can follow you to the final solution! :) – milanbalazs Jun 29 '22 at 20:10