#python #python-3.x #tkinter #mouseevent #tkinter.checkbutton
#python #python-3.x #tkinter #mouseevent #tkinter.checkbutton
Вопрос:
Я хочу создать программу, в которой пользователь может создавать разные кнопки щелчком мыши, эти кнопки должны быть независимыми. С помощью этой логики пользователь может создать контрольную кнопку, которая работает, меняется с зеленой на красную при выборе. Моя проблема в том, что если пользователь снова щелкает мышью, контрольная кнопка перемещается вместо создания новой контрольной кнопки. Есть предложения, как это сделать?
from tkinter import *
root = Tk()
button1 = IntVar()
def color_checkbutton(): # define the colors of the checkbutton
if button1.get() == 1:
example_checkbutton.configure(bg='red')
else:
example_checkbutton.configure(bg='green')
example_checkbutton = Checkbutton(root, variable=button1, textvariable=button1, command=color_checkbutton)
def place_checkbutton_in_canvas(e): # order to insert the checkbutton
xx_and = e.x
yy_and = e.y
example_checkbutton.place(x=xx_and, y=yy_and)
root.bind('<Button-1>', place_checkbutton_in_canvas)
root.mainloop()
Ответ №1:
У вас есть только один example_checkbutton. Всякий раз, когда вы вызываете .place()
метод, эта кнопка перемещается.
Если вы хотите новые, просто создайте их как новые флажки-виджеты:
def place_checkbutton_in_canvas(e): # order to insert the checkbutton
if len(str(e.widget))<3: ## Don't place a new one if a checkbox was clicked
xx_and = e.x
yy_and = e.y
Checkbutton(root, variable=button1, textvariable=button1, command=color_checkbutton).place(x=xx_and, y=yy_and)
Это создает новые контрольные кнопки, которые все связаны с button1
переменной.
Редактировать:
Если вам нужны новые контрольные кнопки, вам придется поддерживать список объектов IntVar() и Checkbutton(), который становится длиннее с каждым щелчком. Приведенный ниже код должен работать. Я также выполняю изменение цвета при создании, чтобы сделать их зелеными и красными.
from tkinter import *
root = Tk()
buttons = []
class CMD: #Auxilliary function for callbacks using parameters. Syntax: CMD(function, argument1, argument2, ...)
def __init__(s1, func, *args):
s1.func = func
s1.args = args
def __call__(s1, *args):
args = s1.args args
s1.func(*args)
def color_checkbutton(pos=0): # define the colors of the checkbutton
if buttons[pos][0].get() == 1:
buttons[pos][2].configure(bg='red')
else:
buttons[pos][2].configure(bg='green')
def place_checkbutton_in_canvas(e): # order to insert the checkbutton
if len(str(e.widget))<3: ## Don't place a new one if a checkbox was clicked
b = IntVar()
pos = len(buttons)
xx_and = e.x
yy_and = e.y
buttons.append([b,pos, Checkbutton(root, variable=b, textvariable=b, command=CMD(color_checkbutton,pos))])
buttons[-1][2].place(x=xx_and, y=yy_and)
color_checkbutton(pos)
root.bind('<Button-1>', place_checkbutton_in_canvas)
root.mainloop()
Комментарии:
1. Спасибо, это создает новые контрольные кнопки, но я предполагаю, что теперь моя проблема в том, что переменная в этих контрольных кнопках должна быть другой. Совместное использование переменной button1 делает их «не независимыми» друг от друга. На самом деле имя контрольной кнопки должно отличаться, чтобы также можно было настраивать цвет независимо. Вот что я не знаю, как это сделать
2. Правка устраняет этот недостаток. Это становится немного сложнее с вспомогательным классом CMD, но он работает и создает столько флажков, сколько вы хотите, которые можно раскрашивать независимо.
3. Просто забудьте о коде CMD. Я использовал этот фрагмент кода в течение 10 лет, прежде чем узнал достаточно об ООП, чтобы действительно понять, что он делает. Просто скопируйте и вставьте его. Это позволяет вам привязывать функции с аргументами к виджетам. Более важной частью здесь является список. Вы можете хранить виджеты и переменные tk в списках, и они сохраняют свою функциональность. Таким образом, вы можете получить и установить их значения, перемещать их и многое другое, просто обратившись к правильному индексу в списке. Я использую эти списки для анкет и т.д. Они весьма полезны.
4. Вы можете сделать это в
color_checkbutton()
функции, которая уже привязана к событию нажатия флажка. В этой функции вы можете посмотреть на состояние всех флажков (.get()
методов первого элемента каждого списка) и что-то сделать, если нужные значения есть1
. На данный момент он проверяет только текущую, но остальные — это всего лишь один индекс списка вверх или вниз. Никаких проблем нет.5.
b
являетсяIntVar()
, который содержит информацию о том, выбрана ли кнопка. Этот первый элемент нужен вам для проверки состояния контрольной кнопки.pos
Элемент немного избыточен. Это просто индекс списка контрольной кнопки (в первом он равен 0, во втором — 1 …). Но вы могли бы использоватьpos
элемент для хранения пары связанных контрольных кнопок, если вы создадите две из них. Таким образом, вы всегда можете проверить их обе, поскольку знаете оба индекса для каждой из кнопок.