Python OOP技术问题:如何在Tkinter第二个窗口类中复用Jira登录实例并解决窗口覆盖问题
解决Tkinter窗口间共享Jira登录实例的问题
我来帮你搞定这个问题!你遇到的核心问题是在Window2中错误地新建了Window1实例——这不仅会覆盖当前的Window2界面,而且新创建的Window1实例里的输入框是空的,根本拿不到之前登录时输入的凭证。正确的做法是在打开Window2时,把Window1中已经创建好的jira_user实例直接传递给Window2,而不是重新创建Window1。
具体修改步骤
给Window2添加接收登录实例的参数
修改Window2的构造方法,新增一个参数来接收传入的jira_user,并保存为自身属性:class Window2(): def __init__(self, master, jira_user): # 新增jira_user参数 self.master = master self.jira_user = jira_user # 保存登录实例 self.master.geometry('500x400') self.frame = tk.Frame(self.master) self.quitButton = tk.Button(self.frame, text = 'Take Data From Jira', width = 25, command = self.take_data) self.quitButton.pack() self.frame.pack()修改Window2的take_data方法
直接用保存的jira_user实例调用方法,不需要再创建Window1:def take_data(self): self.jira_user.take_csd_data() # 直接使用传递过来的登录实例在Window1中传递登录实例给Window2
打开Window2时,把已经登录好的self.jira_user传进去:def new_window(self): self.regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' if(re.fullmatch(self.regex, self.email_entry.get())): self.userLogin() self.master.withdraw() self.toplevel = tk.Toplevel(self.master) Window2(self.toplevel, self.jira_user) # 传递jira_user实例 else: m_box.showerror('Error','Błędny email')
修改后的完整代码
main.py
import tkinter as tk from tkinter import messagebox as m_box from test import Logowanie import re class Window1: def __init__(self, master): self.master = master self.master.geometry('500x400') self.frame = tk.Frame(self.master) self.label = tk.Label(self.master, text='Logowanie', fg='blue', font='Helvetica 16 bold italic') self.label.place(x = 190, y = 100) self.button1 = tk.Button(self.frame, text = 'Log In', width = 25, command = self.new_window).grid(padx = 20, pady = 300) self.token_label = tk.Label(self.master, text='Token') self.token_label.place(x = 120, y = 197) self.email_label = tk.Label(self.master, text='E-mail') self.email_label.place(x = 120, y = 147) self.token_entry = tk.Entry(self.master, width = 25) self.token_entry.place(x = 175, y = 200) self.email_entry = tk.Entry(self.master, width = 25) self.email_entry.place(x = 175, y = 150) self.frame.pack() self.jira_user = None def userLogin(self): self.jira_user = Logowanie('url.atlassian.net/', self.email_entry.get(), self.token_entry.get()) print('LogIn') return self.jira_user def new_window(self): self.regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' if(re.fullmatch(self.regex, self.email_entry.get())): self.userLogin() self.master.withdraw() self.toplevel = tk.Toplevel(self.master) # 传递已登录的jira_user实例给Window2 Window2(self.toplevel, self.jira_user) else: m_box.showerror('Error','Błędny email') class Window2(): def __init__(self, master, jira_user): self.master = master self.jira_user = jira_user # 保存传入的登录实例 self.master.geometry('500x400') self.frame = tk.Frame(self.master) self.quitButton = tk.Button(self.frame, text = 'Take Data From Jira', width = 25, command = self.take_data) self.quitButton.pack() self.frame.pack() def take_data(self): # 直接使用已有的jira_user实例调用方法 self.jira_user.take_csd_data() def main(): root = tk.Tk() app = Window1(root) root.mainloop() if __name__ == '__main__': main()
test.py(修正了两处小错误)
from jira import JIRA class Logowanie(): def __init__(self, adres, mail, token): self.server_url = {'server': adres} self.auth_jira = JIRA(self.server_url, basic_auth=(mail, token)) allfields = self.auth_jira.fields() # 修正推导式的变量名错误 self.nameMap = {field['name']: field['id'] for field in allfields} def take_csd_data(self): # 修正JQL字符串的HTML实体引号问题 for i in self.auth_jira.search_issues(jql_str='project = "Customer Service Desk"', maxResults=100): if str(i.fields.issuetype) == 'RMA' and str(i.fields.status) == 'Pending': print(f'Numer: {i.key} temat sprawy: {i.fields.summary} komponent: ' f'{i.fields.components} przypisana do: {i.fields.assignee} ' f'{getattr(i.fields, self.nameMap["Quantity"])}')
额外说明
- 你之前尝试用
staticmethod解决是行不通的,因为静态方法无法访问实例的属性(比如self.email_entry),而登录凭证是保存在Window1实例中的。 - 类的每个实例都是独立的,当你在Window2中
self.a = Window1(self.master)时,会创建一个全新的Window1实例——它的输入框是空的,还会在当前窗口上绘制Window1的UI,这就是界面被覆盖的原因。 - 我还修正了test.py中的两个小问题:
nameMap推导式的变量名错误,以及JQL字符串中的HTML实体引号"(换成了普通双引号)。
内容的提问来源于stack exchange,提问作者Patryk Kaczm
相关产品推荐
相关产品推荐

