Добавление кнопок в TkInter по нажатию кнопки - PullRequest
0 голосов
/ 20 марта 2019

У меня есть кнопка, и при ее нажатии я хочу создать новую кнопку и новую метку.

Метка должна иметь случайный цвет и должна изменить его при нажатии этой кнопки на другой случайный цвет.

Мой код даже не может правильно добавить кнопки, есть проблемы с размещением новых (размеры странные). Как я могу улучшить это? И как позже я могу создать функцию для новых кнопок, которые будут менять цвета их надписей, потому что у меня нет названий надписей.

import random
from tkinter import *

def color(*args):
    pass

def dump( *args):
    global count

    Butt = Button(root, text="color ", command=color)
    Butt.config(width=int(root.winfo_width() / 10), height=int(root.winfo_height() / 10))
    Butt.grid(row=0, column=count)
    Txt = Label(root, text="Color", bg="#" + ("%06x" % random.randint(0, 16777215)))
    Txt.config(width=int(root.winfo_width() / 10), height=int(root.winfo_height() / 10))
    Txt.grid(row=1, column=count)
    count+=1
    root.mainloop()

count=2
TKroot = Tk()
TKroot.title("Hello")
root = Frame(TKroot)
root.place(relx=0, rely=0, relheight=1, relwidth=1)
root.columnconfigure(0, weight=10)
root.columnconfigure(1, weight=10)
root.rowconfigure(0, weight=10)
root.rowconfigure(1, weight=10)
Butt = Button(root, text="Butt ON")
Butt.bind('<Button-1>', dump)
Butt.config(width=int(root.winfo_width() / 10), height=int(root.winfo_height() / 10))
Butt.grid(row=0, column=0)
Exit = Button(root, text="Quit!", command=root.quit)
Exit.config(width=int(root.winfo_width() / 10), height=int(root.winfo_height() / 10))
Exit.grid(row=0, column=1)
Txt = Label(root, text="This is a label", bg="PeachPuff")
Txt.grid(row=1, column=1, columnspan=1)
TKroot.mainloop()
print("Done")

Ответы [ 2 ]

1 голос
/ 20 марта 2019

ниже объектно-ориентированной версии.

Каждый раз, когда вы нажимаете кнопку Цвет, вы создаете новую метку и новую кнопку

и помещаете ссылку на метку в словарь.

Цвет метки генерируется случайным образом.

После создания, если мы нажимаем на новую кнопку, мы меняем относительный цвет метки.

Самая крутая часть скрипта:

command = lambda which = self.count: self.change_color (which)

лямбда-функция, используемая для сохранения ссылки на кнопку и метку просто

создать, когда мы вызываем функцию change_color.

import tkinter as tk
import random

class App(tk.Frame):

    def __init__(self,):

        super().__init__()

        self.master.title("Hello World")

        self.count = 0
        self.labels = {}

        self.init_ui()

    def init_ui(self):

        self.f = tk.Frame()

        w = tk.Frame()

        tk.Button(w, text="Color", command=self.callback).pack()
        tk.Button(w, text="Close", command=self.on_close).pack()

        w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=0)
        self.f.pack(side=tk.LEFT, fill=tk.BOTH, expand=0)

    def callback(self):

        text_label = "I'm the {} label".format(self.count)
        text_button = "I'm the {} button".format(self.count)

        color = "#" + ("%06x" % random.randint(0, 16777215))
        obj = tk.Label(self.f, text=text_label, bg=color)
        obj.pack()
        self.labels[self.count]=obj
        tk.Button(self.f,
                  text=text_button,
                  command=lambda which=self.count: self.change_color(which)).pack()
        self.count +=1

    def change_color(self,which):

        color = "#" + ("%06x" % random.randint(0, 16777215))
        self.labels[which].config(bg=color)


    def on_close(self):
        self.master.destroy()

if __name__ == '__main__':
    app = App()
    app.mainloop()
1 голос
/ 20 марта 2019

Я вижу несколько проблем с вашим кодом.

1-й, если вы используете place для своего кадра. Это может вызвать проблемы при добавлении новых кнопок, поскольку это не позволит корректно изменить размер окна с новым макетом.

2-й - это то, как вы пишете свой код. Вы называете свой фрейм root и используете метод quit для фрейма, а не для своего корневого окна. То, как вы пишете вещи, усложняет процесс следования, поэтому при написании кода учитывайте рекомендации PEP8.

3-й, вы пытаетесь применить mainloop к вашему фрейму в функции dump. Вам нужен только 1 экземпляр mainloop, и это относится к реальному корневому окну (Tk()).

Чтобы ответить на ваш вопрос о том, как изменить цвет метки позже, я бы использовал список для хранения ваших кнопок и меток. Таким образом, мы можем ссылаться на их значения индекса и применять ваш произвольный цветовой код к меткам при нажатии кнопки.

Я переписал большую часть вашего кода в соответствии с PEP8 и провел общую очистку. Дайте мне знать, если у вас есть какие-либо вопросы.

import tkinter as tk
import random


def color(ndex):
    button_label_list[ndex][1].config(bg="#%06x" % random.randint(0, 16777215))


def dump():
    global count, button_label_list
    button_label_list.append([tk.Button(frame, text="color", command=lambda x=count: color(x)),
                              tk.Label(frame, text="Color", bg="#" + ("%06x" % random.randint(0, 16777215)))])
    button_label_list[-1][0].grid(row=0, column=count, sticky='nsew')
    button_label_list[-1][1].grid(row=1, column=count, sticky='nsew')
    frame.columnconfigure(count, weight=1)
    count += 1


root = tk.Tk()
count = 0
button_label_list = []
root.title("Hello")
root.rowconfigure(1, weight=1)
root.columnconfigure(2, weight=1)

frame = tk.Frame(root)
frame.rowconfigure(1, weight=1)
frame.grid(row=0, column=2, sticky='nsew', rowspan=2)

tk.Button(root, text="butt ON", command=dump).grid(row=0, column=0, sticky='nsew')
tk.Button(root, text="Quit!", command=root.quit).grid(row=0, column=1, sticky='nsew')
tk.Label(root, text="This is a label", bg="PeachPuff").grid(row=1, column=1, columnspan=1, sticky='nsew')

root.mainloop()

Результаты:

Окно, в которое можно добавлять новые кнопки и изменять цвет на каждой этикетке. Основные 2 кнопки, с которых начинается окно, являются статическими в том смысле, что их нельзя вытолкнуть из окна, как в примере с вашим кодом, и они останутся на месте с привязкой слева.

enter image description here

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