Home > other >  how to make multiple tkinter buttons to press together while as user presses any one of them?
how to make multiple tkinter buttons to press together while as user presses any one of them?

Time:10-05

how to make multiple tkinter buttons to press together while as user presses any one of them?

To be clear i want multiple tkinter buttons look like pressed at the same time user presses any one of them .

i tried this:

from tkinter import *
from tkinter import ttk

class one_for_all:
    def __init__(self):
        self.root = Tk()
        self.root.title("One For All, All For One")

        self.frame = ttk.Frame(self.root, padding="3 3 12 12")
        self.frame.grid(row=0, column=0)
        self.root.rowconfigure(0, weight=1)
        self.root.columnconfigure(0, weight=1)
        
        self.btn1 = ttk.Button(self.frame, text="btn1", command=lambda : self.push_all(1))
        self.btn2 = ttk.Button(self.frame, text="btn2", command=lambda : self.push_all(2))
        self.btn3 = ttk.Button(self.frame, text="btn3", command=lambda : self.push_all(3))
        self.btn4 = ttk.Button(self.frame, text="btn4", command=lambda : self.push_all(4))


        self.btn1.grid(row=0, column=0, sticky="nsew")
        self.btn2.grid(row=0, column=1, sticky="nsew")
        self.btn3.grid(row=1, column=0, sticky="nsew")
        self.btn4.grid(row=1, column=1, sticky="nsew")

        for child in self.frame.winfo_children():
            child.grid_configure(padx=5, pady=5)

    def push_all(self, caller):
        if caller != 1:
            self.btn1.configure(command=lambda : None)
            self.btn1.event_generate("<ButtonPress-1>")
            self.btn1.event_generate("<ButtonRelease-1>")
            self.btn1.configure(command=lambda: self.push_all(1))
        if caller != 2:
            self.btn2.configure(command=lambda : None)
            self.btn2.event_generate("<ButtonPress-1>")
            self.btn2.event_generate("<ButtonRelease-1>")
            self.btn2.configure(command=lambda: self.push_all(2))
        if caller != 3:
            self.btn3.configure(command=lambda : None)
            self.btn3.event_generate("<ButtonPress-1>")
            self.btn3.event_generate("<ButtonRelease-1>")
            self.btn3.configure(command=lambda: self.push_all(3))
        if caller != 4:
            self.btn4.configure(command=lambda : None)
            self.btn4.event_generate("<ButtonPress-1>")
            self.btn4.event_generate("<ButtonRelease-1>")
            self.btn4.configure(command=lambda: self.push_all(4))

    def mainloop(self):
        self.root.mainloop()

if __name__ == "__main__":
    one_for_all().mainloop()


but it looks like only button 4 is stimulated by other buttons not all 4 :( Note: i just started the tkinter without any prior experience of GUI

Thanks in Advance.

CodePudding user response:

You can do something like this:

from tkinter import Tk, Button


class MainWindow(Tk):
    def __init__(self):
        super().__init__()

        self.buttons = list()
        for i in range(4):
            button = Button(self, text=f'Button {i}')
            button.bind('<ButtonPress-1>', self.press)
            button.bind('<ButtonRelease-1>', self.release)
            button.pack(fill='both')
            self.buttons.append(button)

    def press(self, event=None):
        for btn in self.buttons:
            btn.config(relief='sunken')

    def release(self, event=None):
        for btn in self.buttons:
            btn.config(relief='raised')


if __name__ == '__main__':
    MainWindow().mainloop()

It will visually make them appear to be clicked at once.

You can simply inherit from Tk and it will reduce the code written a bit since instead of self.root it would simply be just self and the features would be inherited and other stuff, for example, don't need to define mainloop as it is already inherited.

Also:
I strongly suggest following PEP 8 - Style Guide for Python Code. Function and variable names should be in snake_case, class names in CapitalCase. Have two blank lines around function and class declarations.

I strongly advise against using wildcard (*) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2 and so on or import the whole module: import module then You can also use an alias: import module as md or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.

  • Related