2017-04-09 138 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如果你愿意),我终于得到了它与您的代码工作。非常感谢 –

相关问题