簡體   English   中英

如何在 tkinter Text 小部件中實現查找和替換功能?

[英]How do I implement a find and replace function in a tkinter Text widget?

我有以下代碼:

def find_and_replace(self, *args):

        findandreplace = tk.Toplevel(master)
        findandreplace.title('Find & Replace')

        find_label = tk.Label(findandreplace, text='Find')
        find_label.pack(side = tk.LEFT) 
        find_words = tk.StringVar()
        find_entry = tk.Entry(findandreplace, textvariable=find_words)
        find_entry.pack(side = tk.LEFT, fill = tk.BOTH, expand = 1)

        find_button = tk.Button(findandreplace, text='Find', command=self.find)
        find_button.pack(side = tk.LEFT)

        replace_label = tk.Label(findandreplace, text='Replace')
        replace_label.pack(side = tk.LEFT) 
        replace_words = tk.StringVar()
        replace_entry = tk.Entry(findandreplace, textvariable=replace_words)
        replace_entry.pack(side = tk.LEFT, fill = tk.BOTH, expand = 1)
        
        replace_button = tk.Button(findandreplace, text='Replace', command=self.replace)
        replace_button.pack(side = tk.LEFT)

        find_string = find_words.get()
        replace_string = replace_words.get()

        return find_string, replace_string

    
    def find(self, *args):
        self.textarea.tag_remove('found', '1.0', tk.END)
        find_word = self.find_and_replace()[0]
        if find_word:
            idx = '1.0'
            while True:
                idx = self.textarea.search(find_word, idx, nocase=1,
                                            stopindex=tk.END)

                if not idx:
                    break

                lastidx = '% s+% dc' % (idx, len(find_word))
                idx = lastidx
            self.textarea.tag_config('found', foreground='red')
    
    def replace(self, *args):
        self.textarea.tag_remove('found', '1.0', tk.END)
        find_word = self.find_and_replace()[0]
        replace_word = self.find_and_replace()[1]

        if find_word and replace_word:
            idx = '1.0'
            while True:
                idx = self.textarea.search(find_word, idx, nocase=1,
                                            stopindex=tk.END)
                if not idx:
                    break

                lastidx = '% s+% dc' % (idx, len(find_word))
                self.textarea.delete(idx, lastidx)
                self.textarea.insert(idx, replace_word)

                lastidx = '% s+% dc' % (idx, len(replace_word))
                idx = lastidx
            self.textarea.tag_config('found', foreground='green', background='yellow')

我正在使用不同類中的菜單欄來訪問它:

edit_dropdown.add_command(label="Find",
                          command=parent.find)     
edit_dropdown.add_command(label="Replace",
                          command=parent.find_and_replace)

因此, find_and_replace()創建了一個新的tk.Toplevel小部件,我可以在其中訪問find()replace()函數。

但是,當我按下相應的按鈕時,我得到的只是創建了兩個窗口。 我想突出顯示find_words字符串,然后將其替換為replace_words字符串。

我覺得我通過以另一種方式以相反的方式訪問一種方法的變量而搞砸了。

你的問題的根源是這些行:

find_word = self.find_and_replace()[0]
replace_word = self.find_and_replace()[1]

self.find_and_replace創建對話框。 您不想創建新對話框。 相反,您需要訪問當前對話框中的小部件。 這意味着您需要將小部件的引用保存為實例屬性,然后使用這些實例屬性。

注意:您可以通過使用textvariable屬性來降低復雜性。 您只是增加了開銷,因為您沒有利用直接調用條目小部件無法實現的變量的任何功能

例如:

def find_and_replace(self, *args):
    ...
    self.find_entry = tk.Entry(findandreplace)
    self.replace_entry = tk.Entry(findandreplace)
    ...

def replace(self, *args):
    ...
    find_word = self.find_entry.get()
    replace_word = self.replace_entry.get()
    ...

像這樣的事情應該可以解決問題:

from tkinter import *
  
  
# to create a window  
root = Tk()  
  
# root window is the parent window  
fram = Frame(root)  
  
# Creating Label, Entry Box, Button  
# and packing them adding label to 
# search box  
Label(fram, text ='Find').pack(side = LEFT) 
  
# adding of single line text box  
edit = Entry(fram)  
  
# positioning of text box  
edit.pack(side = LEFT, fill = BOTH, expand = 1)  
  
# setting focus  
edit.focus_set()  
  
# adding of search button  
Find = Button(fram, text ='Find') 
Find.pack(side = LEFT) 
  
  
Label(fram, text = "Replace With ").pack(side = LEFT) 
  
edit2 = Entry(fram) 
edit2.pack(side = LEFT, fill = BOTH, expand = 1) 
edit2.focus_set() 
  
replace = Button(fram, text = 'FindNReplace') 
replace.pack(side = LEFT) 
  
fram.pack(side = TOP)  
  
# text box in root window  
text = Text(root)  
  
# text input area at index 1 in text window  
text.insert('1.0', '''Type your text here''')  
text.pack(side = BOTTOM)  
  
# function to search string in text  
def find():  
    # remove tag 'found' from index 1 to END  
    text.tag_remove('found', '1.0', END)  
      
    # returns to widget currently in focus  
    s = edit.get() 
      
    if (s):  
        idx = '1.0'
        while 1:  
            # searches for desried string from index 1  
            idx = text.search(s, idx, nocase = 1,  
                            stopindex = END) 
              
            if not idx: break
            # last index sum of current index and  
            # length of text  
            lastidx = '% s+% dc' % (idx, len(s)) 
  
            # overwrite 'Found' at idx  
            text.tag_add('found', idx, lastidx)  
            idx = lastidx  
  
        # mark located string as red 
          
        text.tag_config('found', foreground ='red') 
    edit.focus_set() 
  
def findNreplace():  
    # remove tag 'found' from index 1 to END  
    text.tag_remove('found', '1.0', END)  
      
    # returns to widget currently in focus  
    s = edit.get() 
    r = edit2.get() 
      
    if (s and r):  
        idx = '1.0'
        while 1:  
            # searches for desried string from index 1  
            idx = text.search(s, idx, nocase = 1,  
                            stopindex = END) 
            print(idx) 
            if not idx: break
              
            # last index sum of current index and  
            # length of text  
            lastidx = '% s+% dc' % (idx, len(s)) 
  
            text.delete(idx, lastidx) 
            text.insert(idx, r) 
  
            lastidx = '% s+% dc' % (idx, len(r)) 
              
            # overwrite 'Found' at idx  
            text.tag_add('found', idx, lastidx)  
            idx = lastidx  
  
        # mark located string as red 
        text.tag_config('found', foreground ='green', background = 'yellow') 
    edit.focus_set() 
                  
Find.config(command = find) 
replace.config(command = findNreplace) 
  
# mainloop function calls the endless  
# loop of the window, so the window will 
# wait for any user interaction till we 
# close it  
root.mainloop() 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM