Tengo un botón de verificación:
from tkinter import * master = Tk() Checkbutton(master, text="Here...").grid(row=0, sticky=W) mainloop()Que se parece a esto:
Traté de mover el botón de verificación al otro lado (para admitir idiomas RTL), por lo que será como:
Here...[]
Sé que puedo dibujar una etiqueta al lado del botón de verificación, pero de esta manera hacer clic en el texto no afectará el botón de verificación.
¿Cómo puedo hacerlo?
Puede vincular el evento de clic del botón izquierdo del mouse de la etiqueta , a una construcción lambda que alterna el botón de verificación:
label.bind("<Button-1>", lambda x : check_button.toggle())Luego, la etiqueta se puede colocar antes del botón de verificación usando la cuadrícula (como se menciona en el OP al final):
from tkinter import * master = Tk() l1 = Label(master, text = "Here...") cb = Checkbutton(master) l1.grid(row = 0, column = 0) cb.grid(row = 0, column = 1, sticky=W) l1.bind("<Button-1>", lambda x : cb.toggle()) mainloop()Esto alternará el botón de verificación incluso si se hace clic en la etiqueta.
SALIDA -:
NOTA:
El botón de verificación ahora debe obtenerse como un objeto ( cb ), para usarse en la construcción lambda para el argumento de devolución de llamada de la función de vinculación de la etiqueta. Por lo tanto, se cuadricula en la siguiente línea. En general, es una buena práctica administrar la geometría por separado, lo que puede evitar errores como este .
Además, como se menciona en la publicación vinculada por @Alexander B. en los comentarios, si este ensamblaje se va a usar varias veces, también se puede convertir en una clase propia que hereda de la clase tkinter.Frame :
class LabeledCheckbutton(Frame): def __init__(self, root, text = ""): Frame.__init__(self, root) self.checkbutton = Checkbutton(self) self.label = Label(self, text = text) self.label.grid(row = 0, column = 0) self.checkbutton.grid(row = 0, column = 1) self.label.bind('<Button-1>', lambda x : self.checkbutton.toggle()) return passUsar esto con grid como administrador de geometría haría que el código completo se viera así:
from tkinter import * class LabeledCheckbutton(Frame): def __init__(self, root, text = ""): Frame.__init__(self, root) self.checkbutton = Checkbutton(self) self.label = Label(self, text = text) self.label.grid(row = 0, column = 0) self.checkbutton.grid(row = 0, column = 1) self.label.bind('<Button-1>', lambda x : self.checkbutton.toggle()) return pass master = Tk() lcb = LabeledCheckbutton(master, text = "Here...") lcb.grid(row = 0, sticky = W) mainloop()El resultado del código anterior sigue siendo consistente con el del primer enfoque. La única diferencia es que ahora es más fácilmente escalable, ya que se puede crear un objeto cuando sea necesario y no es necesario repetir las mismas líneas de código cada vez.
Puede intentar usar ttk.Checkbutton , que puede cambiar su diseño usando ttk.Style().layout(...) :
import tkinter as tk from tkinter import ttk master = tk.Tk() s = ttk.Style() # create a custom Checkbutton style with reverse order of label and indicator s.layout('right.TCheckbutton', [('Checkbutton.padding', {'sticky': 'nswe', 'children': [ ('Checkbutton.focus', { 'side': 'left', 'sticky': 'w', 'children': [('Checkbutton.label', {'sticky': 'nswe'})] }), ('Checkbutton.indicator', {'side': 'left', 'sticky': ''}) ]})] ) ttk.Checkbutton(master, text='Here...', style='right.TCheckbutton').grid(padx=20, pady=10) master.mainloop()Resultado: