Python / Tkinter: используйте кнопку для управления циклом - PullRequest
1 голос
/ 26 апреля 2020

У меня есть for l oop, который предназначен для просмотра списка, отображения некоторых элементов в tkinter, ожидания нажатия кнопки, а затем сохранения некоторых данных Entry и Checkbutton. Код ниже - это MRE из основ того, что я пытаюсь сделать. В приведенном ниже случае, когда нажата Button, я хочу вернуться к loop_function и собрать переменные из button_function.

, я подумал, возможно, используя что-то вроде lambda: continue или lambda: return может вернуть его к первой функции, но эти ошибки выдают.

Есть идеи?

from tkinter import *

class TestClass(Frame):
    def __init__(self, parent=None):
        self.parent = parent
        Frame.__init__(self)
        self.main = self.master
        self.f = Frame(self.parent)
        self.f.pack()

        (Button(self.f, text='Start', 
            command = self.loop_function)
            .grid(column=0, row=0, padx=10, pady=10))

    def loop_function(self):
        name_list = ['Luke', 'Han', 'Leia', 'Chewie']

        for n in name_list:
            self.button_function(n)
            force_user = self.fu.get()
            side = self.sd.get()
            print(n, force_user, side)

    def button_function(self, n):
        self.fu = IntVar(value=1)
        self.sd = StringVar(value='rebel')

        self.fu_e = Checkbutton(self.f, variable=self.fu)
        self.sd_e = Entry(self.f, textvariable=self.sd)

        col = 0
        lbl_list = ['Name', 'Force User?', 'Side']
        for l in lbl_list:
            (Label(self.f, text=l, width=11, anchor=W)
                .grid(column=col, row=0, padx=10, pady=10))
            col += 1

        (Label(self.f, text=n, width=11, anchor=W)
            .grid(column=0, row=1, padx=5))
        self.fu_e.grid(column=1, row=1)
        self.sd_e.grid(column=2, row=1)
        (Button(self.f, text='Save', 
            command = lambda: print('WAIT HERE!!'))
            .grid(column=1, row=2, padx=10, pady=10))

if __name__ == '__main__':
    root=Tk()
    ui = TestClass(root)
    ui.pack()
    root.mainloop()

1 Ответ

1 голос
/ 27 апреля 2020

Я думаю, что следующий код делает то, что вы хотите сделать. После нажатия на кнопку Пуск пользователь получает диалоговое окно, в котором он может ввести свойства первого пользователя Люк . При нажатии на кнопку Сохранить введенные данные сохраняются каким-либо образом. Тогда свойства следующего пользователя ( Han ) могут быть отредактированы.

A для l oop не является правильным подходом здесь. Вместо этого мы хотим прослушивать события нажатия кнопок запуска и сохранения. В моем решении, когда пользователь нажимает Start , вызывается обработчик события pick_next_player. Этот метод всегда выбирает элемент next из итератора, который я обернул вокруг name_list. Затем элементы GUI отображаются с вашим button_function.

Обработчик событий save_action прослушивает событие нажатия кнопки Сохранить . Он собирает значения, введенные пользователем, сохраняет их в self.results и отображает следующего игрока, вызывая pick_next_player.

Когда последний игрок был сохранен, этот сценарий просто печатает строку «закончено». . к консоли. Я предполагаю, что вы собираетесь остановить скрипт или закрыть там диалог. Но это, конечно, зависит от вас.

from tkinter import *


class TestClass(Frame):
    def __init__(self, parent=None):
        self.parent = parent
        Frame.__init__(self)
        self.main = self.master
        self.f = Frame(self.parent)
        self.f.pack()

        (
            Button(self.f, text='Start', command=self.pick_next_player)
                .grid(column=0, row=0, padx=10, pady=10)
        )

        self.name_list = ['Luke', 'Han', 'Leia', 'Chewie']
        self.name_iter = iter(self.name_list)
        self.results = []
        self.current_name = None

    def pick_next_player(self):
        try:
            self.current_name = next(self.name_iter)
        except StopIteration:
            print(f"finished: {self.results}")
            return

        self.button_function()

    def button_function(self):
        self.fu = IntVar(value=1)
        self.sd = StringVar(value='rebel')

        self.fu_e = Checkbutton(self.f, variable=self.fu)
        self.sd_e = Entry(self.f, textvariable=self.sd)

        col = 0
        lbl_list = ['Name', 'Force User?', 'Side']
        for l in lbl_list:
            (Label(self.f, text=l, width=11, anchor=W)
             .grid(column=col, row=0, padx=10, pady=10))
            col += 1

        (
            Label(self.f, text=self.current_name, width=11, anchor=W)
                .grid(column=0, row=1, padx=5)
        )
        self.fu_e.grid(column=1, row=1)
        self.sd_e.grid(column=2, row=1)
        (
            Button(self.f, text='Save', command=self.save_action)
                .grid(column=1, row=2, padx=10, pady=10)
        )

    def save_action(self):
        force_user = self.fu.get()
        side = self.sd.get()
        print(f"saving {self.current_name}, {force_user}, {side}")
        self.results.append({'name': self.current_name, 'force': force_user, 'faction': side})
        self.pick_next_player()


if __name__ == '__main__':
    root = Tk()
    ui = TestClass(root)
    ui.pack()
    root.mainloop()


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...