我有一个在TeamCity中创建构建的脚本。我正在尝试创建一个使用Tkinder完成此操作的gui。有多个步骤(即获取凭据 - >输入buildname - >添加模板 - >等),因此我使用多个框架使用show_frame()
命令创建步骤。我的问题如下:我进行了多次REST调用,因此第一步是获取用户的用户名和密码。但是,由于所有页面在程序启动时都已初始化,因此所有使REST调用的方法都会出错,因为它们还没有凭据。
如何让后续步骤(及其方法)等待用户输入用户名和密码?
从下面的代码中,(在PageOne类中)我试图通过REST调用从BitBcuket获取项目列表,这样我就可以动态地将菜单项添加到菜单中,但我无法弄清楚如何等待获取用户名和密码。
import json
import requests
import Tkinter as tk
import tkMessageBox
TITLE_FONT = ("Arial", 18, "bold")
class CreateBuild(tk.Tk):
def __init__(self, *args, **kwargs):
self.username = None
self.password = None
self.bit_projects = None
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
def authenticate(self, username, password):
r = requests.head('https://source.amirsys-int.com/projects', auth=(username, password))
if r.status_code == 405:
self.username = username
self.password = password
self.show_frame("PageOne")
else:
tkMessageBox.showinfo("Error", "Incorrect username and/or password.\nPlease enter your Crowd username and "
"password.")
def get_bitbucket_projects(self):
r = requests.get('https://source.amirsys-int.com/rest/api/1.0/projects', auth=(self.username,
self.password))
j = json.loads(r.text)
size = j['size']
repo_dic = {}
for i in range(0, size):
name = j['values'][i]['name']
repo_id = j['values'][i]['key']
repo_dic[name] = repo_id
self.bit_project = repo_dic
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
instructions = tk.Label(self, text="Please enter your Crowd credentials", font=TITLE_FONT)
instructions.grid(column=1, row=1, columnspan=3, padx=30, pady=30)
username = tk.Label(self, text="Crowd Username: ")
username.grid(column=1, row=2, columnspan=2)
password = tk.Label(self, text="Crowd Password: ")
password.grid(column=1, row=3, columnspan=2)
username_entry = tk.Entry(self)
username_entry.grid(column=3, row=2)
password_entry = tk.Entry(self, show="*")
password_entry.grid(column=3, row=3)
button = tk.Button(self, text="Next", command=lambda: controller.authenticate(username_entry.get(),
password_entry.get()))
button.grid(column=4, row=4, padx=10, pady=10)
self.grid_rowconfigure(5, weight=1)
self.grid_columnconfigure(5, weight=1)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
instructions = tk.Label(self, text="Enter build information", font=TITLE_FONT)
instructions.grid(column=1, row=1, columnspan=3, padx=30, pady=30)
build_name = tk.Label(self, text="Build Name: ")
build_name.grid(column=1, row=2, columnspan=2)
build_name_entry = tk.Entry(self)
build_name_entry.grid(column=3, row=2)
project_key = tk.Label(self, text="BitBucket Project: ", anchor="w")
project_key.grid(column=1, row=3, columnspan=2)
project_menu = tk.Menubutton(self, text="Project", anchor="w")
project_menu.grid(column=3, row=3, columnspan=2)
project_menu.menu = tk.Menu(project_menu)
for key, value in controller.bit_projects:
project_menu.menu.add_checkbutton(label=key, variable=value)
self.grid_rowconfigure(4, weight=1)
self.grid_columnconfigure(4, weight=1)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
if __name__ == "__main__":
app = CreateBuild()
app.geometry("800x600")
app.title("Create TeamCity Build")
app.mainloop()
答案 0 :(得分:1)
您需要将该代码移出__init__方法(在程序启动时运行),并移动到显示框架时调用的方法:tkraise()。
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
instructions = tk.Label(self, text="Enter build information", font=TITLE_FONT)
instructions.grid(column=1, row=1, columnspan=3, padx=30, pady=30)
build_name = tk.Label(self, text="Build Name: ")
build_name.grid(column=1, row=2, columnspan=2)
build_name_entry = tk.Entry(self)
build_name_entry.grid(column=3, row=2)
project_key = tk.Label(self, text="BitBucket Project: ", anchor="w")
project_key.grid(column=1, row=3, columnspan=2)
self.project_menu = tk.Menubutton(self, text="Project", anchor="w")
self.project_menu.grid(column=3, row=3, columnspan=2)
self.project_menu.menu = tk.Menu(self.project_menu)
self.grid_rowconfigure(4, weight=1)
self.grid_columnconfigure(4, weight=1)
def tkraise(self):
for key, value in self.controller.bit_projects:
self.project_menu.menu.add_checkbutton(label=key, variable=value)
tk.Frame.tkraise(self) # call the superclass to actually raise the frame