admin管理员组

文章数量:1122832

Translated from Russian using Google Translate

Version python 3.12, win 10 64x
I'm trying to write a program that would create documents in accordance with the selected checkbutton for each user. However, I can't get the checkbutton status for each user. After calling the raspredelenie_polzovateley function on the sozdanie button to work with checkbutton states, the terminal displays, that all checkbuttons have None. What could be the problem?

P.s. spisok_list is the list of users that I get in the earlier part of the code. Below is just part of the code that creates a checkbutton window for each user. In other parts of the code, what is presented below is not overwritten or changed

P.s.s. I'm using the basic tkinter built in python, not the custom one

def vibor_zayvok_button():
    # Расчет необходимых размеров окна
    height_polzovateley = 25  # Высота каждого Label
    padding = 20  # Отступ от краев
    kol_vo_polzovateley = len(spisok_list)

    # Высота окна на основе количества Label (с учетом заголовка и отступов)
    height_okoshka = padding * 3 + kol_vo_polzovateley * (height_polzovateley+13) + 160  # +40 для кнопки "Закрыть"
    width_okoshka = 1100  # Ширина окна для текста + отступы

    # Создаем новое окно
    okoshko_parametr = Tk()
    okoshko_parametr.title('Выбор заявок для пользователей')
    okoshko_parametr.geometry(f'{width_okoshka}x{height_okoshka}')

    # Заголовок окна
    polzovatel_spisok = ttk.Label(okoshko_parametr, text="Список пользователей", font='Osnova 14')
    polzovatel_spisok.place(x=padding, y=padding+100)


canvas_data = [
        {"text": "Созд.", "x_positions": [416, 481, 546, 611, 676, 741, 806, 871, 936, 1001], "y_position": 113},
        {"text": "Восс.", "x_positions": [432, 497, 562, 627, 692, 757, 822, 887, 952, 1017], "y_position": 113},
        {"text": "Блок.", "x_positions": [447, 512, 577, 642, 707, 772, 837, 902, 967, 1032], "y_position": 113},
        {"text": "1", "x_positions": [270], "y_position": 100},
        {"text": "2", "x_positions": [295], "y_position": 90},
        {"text": "3", "x_positions": [320], "y_position": 100},
        {"text": "4", "x_positions": [344], "y_position": 100},
        {"text": "5", "x_positions": [369], "y_position": 100},
        {"text": "6", "x_positions": [416, 431, 446], "y_position": 50},
        {"text": "7", "x_positions": [480, 495, 510], "y_position": 31},
        {"text": "8", "x_positions": [545, 560, 575], "y_position": 42},
        {"text": "9", "x_positions": [610, 625, 640], "y_position": 46},
        {"text": "10", "x_positions": [675, 690, 705], "y_position": 45},
        {"text": "11", "x_positions": [740, 755, 770], "y_position": 35},
        {"text": "12", "x_positions": [805, 820, 835], "y_position": 28},
        {"text": "13", "x_positions": [870, 885, 900], "y_position": 35},
        {"text": "14", "x_positions": [935, 950, 965], "y_position": 50},
        {"text": "15", "x_positions": [1000, 1015, 1030, 1045, 1060], "y_position": 45},
        {"text": "Расш.", "x_positions": [1047], "y_position": 112},
        {"text": "Измн.", "x_positions": [1062], "y_position": 111}
    ]
    # Цикл для создания Canvas и размещения текста
    for data in canvas_data:
        for x_position in data["x_positions"]:
            canvas = Canvas(okoshko_parametr, width=15, height=67, highlightthickness=0)
            canvas.place(x=x_position, y=data["y_position"])
            canvas.create_text(10, 30, text=data["text"], angle=90, font="Osnova 9")
            canvas.update_idletasks()

    # Добавляем по одному Label для каждого пользователя из spisok_list
    y_position = padding * 3 # Начальная позиция по оси y (под заголовком)
    vibrannie_zayvki={}
    for i, polzovatel in enumerate(spisok_list):
        polzovatel_label = ttk.Label(okoshko_parametr, text=polzovatel, font='Osnova 12')
        polzovatel_label.place(x=padding, y=y_position+100)

        vibrannie_zayvki[polzovatel] = []
        x_position = padding+253
        for j in range(37):
            var = tkinter.BooleanVar()
            var.trace_add("write", lambda *args, u=polzovatel, idx=j: print(
                f'Переменная для {u}, чекбокс {idx + 1}, изменилась: {var.get()}'))
            vibrannie_zayvki[polzovatel].append(var)
            chekbox = ttk.Checkbutton(okoshko_parametr,variable=var)
            

            #Цикл расстановки чекбоксов
            if 0 <= j <= 4:  # Первые 4 чекбокса
                chekbox.place(x=x_position, y=y_position+100)
                x_position += 25

            elif 5 <= j <= 31:
                group_index = (j - 5) // 3  # Номер тройки (от 0 до 8)
                position_in_group = (j - 5) % 3  # Позиция внутри тройки (0, 1, 2)

                if position_in_group == 0:  # Первый чекбокс тройки
                    x_position += 20  # Отступ между тройками
                chekbox.place(x=x_position, y=y_position+100)
                x_position += 15  # Интервал 15 пикселей внутри тройки

            elif j > 31:  # Последние 5 чекбоксов
                if j == 32:  # Отступ перед последними 5 чекбоксами
                    x_position += 20
                chekbox.place(x=x_position, y=y_position+100)
                x_position += 15  # Интервал 15 пикселей между чекбоксами
            print (f"Создан чекбокс {j+1} для {polzovatel}, var_id : {id(var)}, var.get() = {var.get()}")
        y_position += (height_polzovateley*1.5)  # Смещаемся для следующего пользователя
        okoshko_parametr.update()


def raspredelenie_polzovateley():
        for user, var_list in vibrannie_zayvki.items():
            print(f'Пользователь: {user}')
            for index, var in enumerate(var_list):
                state = 'выбран' if var.get() else print (var.get())
                print(f'- Чекбокс {index+1}: {state}')
    sozdanie = ttk.Button(okoshko_parametr, text='Создать заявки в папку:', command=raspredelenie_polzovateley)
    sozdanie.place(x=padding, y=height_okoshka-padding-10)

I tried ChatGPT since I couldn't find an answer online, but it didn't give me a good answer either. Using it, I tried to track the id of each checkbutton in a loop and when calling the raspredelenie_polzovateley function. I found out that all ids match.

Tried tracking the state via partial and trace_add, if the checkbutton state changes, but the terminal was silent, since the state did not change after creation

本文标签: tkintercheckbuttonCheckbutton state not updating in tkinter pythonStack Overflow