python - 有没有办法可以在 tkinter 多窗口的两个不同窗口上使用两个相同的自动完成输入框?
问题描述
这段代码的问题是我有两个自动完成输入框,一个在 Win1 中,另一个在 Win3 中。虽然它在 Win1 中工作,但问题是当我点击 Win3 时,新的输入框出现在 win1 中。self.entername_e 用于接收 Win3 上的条目,self.name_e 用于接收 Win1 上的条目
import tkinter as tk
from tkinter import *
import sqlite3
import tkinter.messagebox
import datetime
import math
import os
import random
import re
AutocompleteEntry 是 Windows Win1 和 Win3 都使用的类
#This is the Autocomplete class both the entries will use
class AutocompleteEntry(Entry):
def __init__(self, autocompleteList, *args, **kwargs):
# Listbox length
if 'listboxLength' in kwargs:
self.listboxLength = kwargs['listboxLength']
del kwargs['listboxLength']
else:
self.listboxLength = 8
# Custom matches function
if 'matchesFunction' in kwargs:
self.matchesFunction = kwargs['matchesFunction']
del kwargs['matchesFunction']
else:
def matches(fieldValue, acListEntry):
pattern = re.compile('.*' + re.escape(fieldValue) + '.*', re.IGNORECASE)
return re.match(pattern, acListEntry)
self.matchesFunction = matches
Entry.__init__(self, *args, **kwargs)
self.focus()
self.autocompleteList = autocompleteList
self.var = self["textvariable"]
if self.var == '':
self.var = self["textvariable"] = StringVar()
self.var.trace('w', self.changed)
self.bind("<Right>", self.selection)
self.bind("<Up>", self.moveUp)
self.bind("<Down>", self.moveDown)
self.listboxUp = False
def changed(self, name, index, mode):
if self.var.get() == '':
if self.listboxUp:
self.listbox.destroy()
self.listboxUp = False
else:
words = self.comparison()
if words:
if not self.listboxUp:
self.listbox = Listbox(width=self["width"], height=self.listboxLength)
self.listbox.bind("<Button-1>", self.selection)
self.listbox.bind("<Right>", self.selection)
self.listbox.place(x=self.winfo_x(), y=self.winfo_y() + self.winfo_height())
self.listboxUp = True
self.listbox.delete(0, END)
for w in words:
self.listbox.insert(END,w)
else:
if self.listboxUp:
self.listbox.destroy()
self.listboxUp = False
def selection(self, event):
if self.listboxUp:
self.var.set(self.listbox.get(ACTIVE))
self.listbox.destroy()
self.listboxUp = False
self.icursor(END)
def moveUp(self, event):
if self.listboxUp:
if self.listbox.curselection() == ():
index = '0'
else:
index = self.listbox.curselection()[0]
if index != '0':
self.listbox.selection_clear(first=index)
index = str(int(index) - 1)
self.listbox.see(index) # Scroll!
self.listbox.selection_set(first=index)
self.listbox.activate(index)
def moveDown(self, event):
if self.listboxUp:
if self.listbox.curselection() == ():
index = '0'
else:
index = self.listbox.curselection()[0]
if index != END:
self.listbox.selection_clear(first=index)
index = str(int(index) + 1)
self.listbox.see(index) # Scroll!
self.listbox.selection_set(first=index)
self.listbox.activate(index)
def comparison(self):
return [ w for w in self.autocompleteList if self.matchesFunction(self.var.get(), w) ]
这是代码开始的地方
class Win1:
def __init__(self, master):
self.master = master
self.master = master
autocompleteList = [ 'Milo tin', 'Shito small', 'Deodorant', 'Spray']
def matches(fieldValue, acListEntry):
pattern = re.compile(re.escape(fieldValue) + '.*', re.IGNORECASE)
return re.match(pattern, acListEntry)
self.master.geometry("400x300")
self.show_widgets()
这是Win1上的AutocompleteEntry
#Autocomplete Entry
self.name_e = AutocompleteEntry(autocompleteList, listboxLength=10, width=25, font=('arial 18 bold'), bg='lightblue', matchesFunction=matches)
self.name_e.place(x=260, y=150)
def show_widgets(self):
self.frame = tk.Frame(self.master)
self.master.title("Window n.1")
self.create_button("Click to open Window 2", Win2)
self.create_button("Click to open Window 3", Win3)
self.frame.pack()
def create_button(self, text, _class):
"Button that creates a new window"
tk.Button(self.frame, text=text,command=lambda: self.new_window(_class)).pack()
def new_window(self, _class):
self.win = tk.Toplevel(self.master)
_class(self.win)
class Win2(Win1):
def __init__(self, master):
self.master = master
self.master.title("Window n.2")
self.master.geometry("400x100+200+200")
self.show_widgets()
def show_widgets(self):
"A frame with a button to quit the window"
self.frame = tk.Frame(self.master, bg="red")
self.quit_button = tk.Button(self.frame, text=f"Quit this window n. 2",command=self.close_window)
self.quit_button.pack()
self.create_button("Open window 3 from window 2", Win3)
self.frame.pack()
def close_window(self):
self.master.destroy()
class Win3(Win1):
def __init__(self, master):
self.master = master
self.master = master
#This is the list of the autocomplete entry
autocompleteList = [ 'Milo tin', 'Shito small', 'Deodorant', 'Spray' ]
def matches(fieldValue, acListEntry):
pattern = re.compile(re.escape(fieldValue) + '.*', re.IGNORECASE)
return re.match(pattern, acListEntry)
self.master.title("Window n.3")
self.master.geometry("400x200+200+200")
self.show_widgets()
这也是 Win3 上的 AutocompleteEntry
#Autocomplete Entry
self.entername_e = AutocompleteEntry(autocompleteList, listboxLength=10, width=25, font=('arial 18 bold'), bg='white', matchesFunction=matches)
self.entername_e.place(x=260, y=150)
def show_widgets(self):
self.frame = tk.Frame(self.master, bg="green")
self.quit = tk.Button(self.frame, text=f"Quit this window n. 3",command=self.close_window)
self.quit.pack()
self.label = tk.Label(self.frame, text="THIS IS ONLY IN THE THIRD WINDOW")
self.label.pack()
self.frame.pack()
def close_window(self):
self.master.destroy()
root = tk.Tk()
app = Win1(root)
root.mainloop()
解决方案
推荐阅读
- java - 为什么 ALBUM_ART 是唯一一个在其他人都很好的情况下从 MediaStore 返回 null 的字段?
- python - 卷积神经网络查询
- java - Java 链表类
- webpack - 未找到模块:错误:无法解析 './foo/foo.scss' in
- python - 在 Jupyter notebook 中使用 OpenCV 查看 tif 图像文件
- c++ - 通过 boost::lexical_cast (segfault) 添加转换类型
- plotly - plotly.js:堆叠条形图中一个条的悬停文本
- php - 如何使用 Slim 框架上传图片
- python - 使用 Flask 导入引导程序
- google-apps-script - 如何在 Google Apps Scripts 中使用 Google 服务帐户通过 IAM 进行身份验证?