2016-02-27 3 views
1

Я любительский программист на Python с 2-месячным опытом. Я пытаюсь написать список задач GUI через tkinter. Фактическое размещение кнопок не важно. Я могу поиграть с ними после. Мне нужна помощь в отображении добавленного элемента в список. В программе он хорошо обновляется по значению, но он не будет печататься в списке. Я дважды проверил его на консоли и сказал «tkinter.StringVar object at 0x102fa4048», но не обновил фактический список. Мне нужна помощь в том, как я могу обновить список Main_Q в столбце ярлыков? Очень ценю некоторую направленность и помощь в кодировании. Благодарю.python tkinter append list

Main_Q =["read","clean dishes", "wash car"] 


from tkinter import* 
root=Tk(className="total tasks in the Q") 


#formula 

def update(): 
global Main_Q 
a=len(Main_Q) 
num.set(a) 

def add2list(): 
Main_Q.append(name) 
a=len(Main_Q) 
num.set(a) 
print (Main_Q) 


#output 

num=StringVar() 
y=Label(root, textvariable=num).grid(row=0, column=1) 

#input 

name=StringVar() 
b=Entry(root, textvariable=name).grid(row=7,column=0) 


#buttons 
z=Button(root, text="update", command=update).grid(row=7, column=2) 
add2list=Button(root,text="add", command=add2list).grid(row=7,   
column=1) 


r = 0 
for c in Main_Q: 
Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0) 
r = r + 1 

root.mainloop() 

ответ

0

Ваша проблема в том, что ваш цикл, который строить свои метки не получает окликнул каждый раз, когда вы ввели новую «задачу». Чтобы легко исправить это, вы можете переместить этот цикл в свою функцию обновления.

Если вы хотите, чтобы предотвратить пробегаем через виджет каждый раз, когда вы можете создать новый список со всеми виджетами, которые уже были созданы:

createdWidgets = [] 
widgetsQueue = [] 

В функции обновления вы, чем нужно перебирать widgetsQueue (widgetsQueue .pop()), создайте виджеты и добавьте виджет в список createdWidgetes.

def update(): 
    global Main_Q 
    r = 0 
    for c in Main_Q: 
     Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0) 
     r += 1 # shorthand for r = r + 1 

Некоторые аддитивные примечания:

  1. для вступления его легче отделить определение и размещение:

    b = Entry(root) 
    b.grid(row=7,column=0) 
    

    , потому что, чем запись() возвращает экземпляр и вы может использовать его для получения текста:

    b.get() 
    
  2. Если вы идете по магазинам, вы бросаете все в одну сумку?

    from tkinter import * 
    

    делает axactly, что (в данном случае Глобалы() переменная будет мешок) .Если вы хотите узнать больше о том, что Importing Python Modules. Чтобы предотвратить это, и сократить количество писем типа:

    import tkinter as t # or tk 
    root = t.Tk() 
    

* Но конечно, если вы просто хотите небольшая программа его хорошо.

+0

Добрый день Sense4. Спасибо за комментарии и направление. Я сделал то, что вы просили меня сделать, чтобы поставить цикл for в кнопку «Обновить». Теперь он обновляется в цикле for, но он все еще не печатает то, что я ввел. Например, если я набираю «душ», он печатает «PY_VAR1». И в IDLE он печатает ". Еще раз спасибо. После этого выяснилось, что я начну узнавать, как использовать функцию« destroy »и кнопку Return для обновления. «Сначала мои, чтобы увидеть, могу ли я это понять. :) – fishtang

+0

Эй, для этого вам стоит взглянуть на мои примечания о добавлении. Я не знаю, возможно ли это также с помощью stringVar, но я всегда использую метод, который у меня есть упомянутый там для записи. Удачи. – Sens4

0

Дизайн:

Чтобы решить проблему, вам необходимо разработать это простое решение:

  1. восстановить текст Tkinter.Entry виджета с помощью get() метода.
  2. добавить текст, который вы получили в , Main_Q используя append() метод.
  3. свяжите кнопку, которая обновляется по щелчку и Main_Q, и ваш графический интерфейс с использованием метода command.
  4. создать новый Tkinter.Виджет метки, установите его текст в значение, которое вы получили в 1, и увеличите его соответствующую строку в графическом интерфейсе.

Я предпочитаю, чтобы организовать свой код в класс, который содержит конструктор, где Main_Q инициализируется так, что мы называем initialize_user_interface() для инициализации графического интерфейса пользователя с его тремя элементами:

def __init__(self, parent): 
      Tkinter.Frame.__init__(self, parent) 
      self.parent = parent 
      self.Main_Q = ["read", "clean dishes", "wash car"] 
      self.r = 0 # position of the row of each label 
      self.initialize_user_interface() 

Метод initialize_user_interface() делает то, что его имя говорит. Мы главным образом связать функцию update_gui(), которая вставляет новую метку с текстом набора на то, что пользователь вводит в Tkinter.Entry виджет с помощью command = self.update_gui

ef initialize_user_interface(self): 
     self.parent.title("Update GUI") 
     self.parent.grid_rowconfigure(0, weight = 1) 
     self.parent.grid_columnconfigure(0, weight = 1) 

     for e in self.Main_Q: 
      Tkinter.Label(self.parent, anchor = Tkinter.W, text = e).grid(row = self.r, sticky = Tkinter.W) 
      self.r+=1 
     self.entry_text = Tkinter.Entry(self.parent) 
     self.entry_text.grid(row = 0, column = 1) 
     self.button_update = Tkinter.Button(self.parent, text = "Update", command = self.update_gui).grid(row = 1, column = 1, sticky = Tkinter.E) 

Наконец, ничего проще, чем update_gui() функция:

def update_gui(self): 
     self.r+=1 # increment the row reserved to the new label 
     self.Main_Q.append(self.entry_text.get()) 
     Tkinter.Label(self.parent, anchor = Tkinter.W, text = self.entry_text.get()).grid(row = self.r, sticky = Tkinter.W) 

Программирование приложение:

Вот полная программа:

''' 
Created on Mar 11, 2016 

@author: Bill BEGUERADJ 
''' 
import Tkinter 


class Begueradj(Tkinter.Frame): 
    def __init__(self, parent): 
     Tkinter.Frame.__init__(self, parent) 
     self.parent = parent 
     self.main_queue = ["read", "clean dishes", "wash car"] 
     self.r = 0 
     self.initialize_user_interface() 


    def initialize_user_interface(self): 
     self.parent.title("Update GUI") 
     self.parent.grid_rowconfigure(0, weight = 1) 
     self.parent.grid_columnconfigure(0, weight = 1) 

     for e in self.main_queue: 
      Tkinter.Label(self.parent, anchor = Tkinter.W, text = e).grid(row = self.r, sticky = Tkinter.W) 
      self.r+=1 
     self.entry_text = Tkinter.Entry(self.parent) 
     self.entry_text.grid(row = 0, column = 1) 
     self.button_update = Tkinter.Button(self.parent, text = "Update", command = self.update_gui).grid(row = 1, column = 1, sticky = Tkinter.E) 

    def update_gui(self): 
     self.r+=1 
     self.main_queue.append(self.entry_text.get()) 
     Tkinter.Label(self.parent, anchor = Tkinter.W, text = self.entry_text.get()).grid(row = self.r, sticky = Tkinter.W) 


def main(): 
    root = Tkinter.Tk() 
    b = Begueradj(root) 
    root.mainloop() 

if __name__ == "__main__": 
    main() 

Демо:

Вот скриншот запущенной программы:

enter image description here

Примечание:

Я закодирован предыдущую программу с помощью Python 2.7, так что если вы хотите, чтобы проверить его , пожалуйста, измените Tkinter на tkinter. Все остальное остается прежним.

+0

Привет, Бил, очень спасибо за помощь. Я никогда бы не подумал написать это так. Я понимаю концепцию класса, но не на 100% понятен. Этот пример помогает совсем немного. Я бы хотел добавить дополнительную функцию к этому небольшому упражнению, чтобы продолжить свое обучение. Еще раз спасибо. – fishtang

+0

Добро пожаловать. Если вы не понимаете что-то с моим кодом, пожалуйста, не стесняйтесь спрашивать меня в любое время. @fishtang –

+0

Привет, Билл, Уу Если бы вы так любезно объяснили мне, почему два заявления? Благодарю. Я видел несколько кодов с только одним оператором init, а некоторые с 2. классом Begueradj (Tkinter.Frame): def __init __ (self, parent): Tkinter.Frame .__ init __ (self, parent) self.parent = parent – fishtang