2017-04-09 95 views
0

在我正在使用Python 3.6 Tkinter的一個項目工作的時刻。目前,我正在嘗試爲用戶提供訪問權限OptionMenu,以便放置「用戶」或「管理員」。我嘗試了各種方法,但似乎無法自己修復它或在網上找到有用的文檔。 問題不是在製造和OptionMenu顯示它,也不是該STRINGVAR變量的值沒有改變。問題是,當選擇任何新選項時,OptionMenu內部的文本不會改變。的Tkinter OptionMenu小部件不顯示值

class UsersDetailsEditPage(Tk): 
def __init__(self, *args, **kwargs): 
    Tk.__init__(self, *args, **kwargs) 
    self.title("Edit User Details") 
    self.option_add("*Font", 'TkDefaultFont') 

    self.noteBook = ttk.Notebook(self) 

    for i in range(len(users)): 
     self.noteBook.add(self.getUserViewFrame(users[i]), text=users[i][2]) 
    self.noteBook.pack() 

    self.resizable(width=False, height=False) 

def getUserViewFrame(self, user): 
    frame = Frame(self) 
    frame.grid_rowconfigure(1, weight=1) 
    frame.grid_columnconfigure(1, weight=1) 

    Label(frame, text="User's name:").grid(row=0, column=0, sticky=W) 
    nameText = Text(frame, height=1, width=20) 
    nameText.insert("1.0", user[2]) 
    nameText.edit_reset() 
    nameText.grid(row=0, column=1, sticky=E) 

    Label(frame, text="Username:").grid(row=1, column=0, sticky=W) 
    usernameText = Text(frame, height=1, width=20) 
    usernameText.insert("1.0", user[0]) 
    usernameText.edit_reset() 
    usernameText.grid(row=1, column=1, sticky=E) 

    Label(frame, text="Password:").grid(row=2, column=0, sticky=W) 
    passwordText = Text(frame, height=1, width=20) 
    passwordText.insert("1.0", user[1]) 
    passwordText.edit_reset() 
    passwordText.grid(row=2, column=1, sticky=E) 

    # the constructor syntax is: 
    # OptionMenu(master, variable, *values) 

    Label(frame, text="User Access:").grid(row=3, column=0, sticky=W) 
    self.options = StringVar() 
    self.options.set("User") 

    self.userAccessDrop = ttk.OptionMenu(frame, self.options, "User", *("User", "Admin")) 
    self.userAccessDrop.config(width=10) 
    self.userAccessDrop.grid(row=3, column=1, sticky=E) 

    return frame 

This is the output of the code

我需要的所有庫進口(我認爲):

from tkinter import * 
from tkinter import messagebox 
import tkinter.ttk as ttk 
import csv 
import os 

如果任何人都可以計算出如何使這項工作,這將是大加讚賞。 感謝

回答

1

我想你的代碼,它爲我工作。我只能猜測這是一個垃圾回收問題。嘗試將選項菜單分配給框架而不是自己,這樣它就不會被覆蓋。

frame.options = StringVar() 
frame.options.set("User") 

frame.userAccessDrop = ttk.OptionMenu(frame, frame.options, "User", *("User", "Admin")) 
frame.userAccessDrop.config(width=10) 
frame.userAccessDrop.grid(row=3, column=1, sticky=E) 

你真的應該重寫這個,這樣你就可以創建一個Frame來創建用戶實例。

編輯:例如:

import tkinter as tk 
from tkinter import ttk 

class UserFrame(tk.Frame): 
    def __init__(self, master=None, data=None, **kwargs): 
     tk.Frame.__init__(self, master, **kwargs) 

     data = data[2], data[0], data[1] # rearrange data 
     labels = ("User's name:", "Username:", "Password:") 
     for row, (label, value) in enumerate(zip(labels, data)): 
      lbl = tk.Label(self, text=label) 
      lbl.grid(row=row, column=0, sticky=tk.W) 
      ent = tk.Entry(self) 
      ent.insert(0, value) 
      ent.grid(row=row, column=1, sticky=tk.E) 

     lbl = tk.Label(self, text="User Access:") 
     lbl.grid(row=3, column=0, sticky=tk.W) 
     self.options = tk.StringVar(self, "User") 

     self.userAccessDrop = ttk.OptionMenu(self, 
      self.options, 
      "User", # starting value 
      "User", "Admin", # options 
      ) 
     self.userAccessDrop.config(width=10) 
     self.userAccessDrop.grid(row=len(labels), column=1, sticky=tk.E) 

class UsersDetailsEditPage(tk.Tk): 
    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 
     self.title("Edit User Details") 
     self.option_add("*Font", 'TkDefaultFont') 

     self.noteBook = ttk.Notebook(self) 

     for user in users: 
      self.noteBook.add(UserFrame(self, user), text=user[2]) 
     self.noteBook.pack() 

     self.resizable(width=False, height=False) 

這真的不是功能上你有什麼什麼不同,只是更簡潔的代碼(這實際上使得編碼時間的巨大差異)。注意我也擺脫了邪惡的通配符導入,並縮小了你的代碼。請記住,如果您正在複製和粘貼代碼塊,那麼您正在執行計算機的工作。我還將您移至了Entry小部件,它們是單行文本小部件。此外,儘量避免「便利」初始化並在同一行上佈置小部件。它很醜並且會導致錯誤。

我用「自我」在爲「self.options」和「self.userAccessDrop」,但由於我們的子類的框架,「自我」,現在指的是框架實例。換句話說,就像我上面的塊一樣,我使用了「frame.options」。

+0

@Jonathon隨着用戶數量未定(因爲它們是從一個文件中獲得並生成使用該信息的二維數組),我覺得我可以真正做到爲每一個用戶進入一個框架的唯一辦法筆記本小部件是爲每個用戶生成一個框架然後遍歷數組中的每個用戶。如果你有什麼方法可以做你說的話,那將會非常感謝 –

+0

我用一個例子編輯了我的答案。 – Novel

+0

@Jonathon哦,對了,我沒有看到之前,完整的例子(因爲我是個白癡!),以及一些修補後(或tkintering如果你願意),我終於得到了它與您的代碼工作。非常感謝 –