简体   繁体   English

在 tkinter 中选择多个文本

[英]Selecting multiple text in tkinter

Is there any way to select multiple text in tkinter?有没有办法在 tkinter 中 select 多个文本?

Here's the code:这是代码:

from tkinter import *

root = Tk()

text = Text(root , width = 65 , height = 20 , font = "consolas 14")
text.pack()

text.insert('1.0' , "This is the first line.\nThis is the second line.\nThis is the third line.")

mainloop()

Here, I want be able to select multiple text from where ever I want.在这里,我希望能够从我想要的任何地方 select 多个文本。

Here is an Image(GIF) that explains what I mean:这是一个解释我的意思的图像(GIF):

在此处输入图像描述

Is there any way to achieve this in tkinter?有没有办法在 tkinter 中实现这一点?

It would be great if anyone could help me out.如果有人可以帮助我,那就太好了。

I made a short demo, with Control key hold you could select multiple text.我做了一个简短的演示,按住Control键可以 select 多个文本。 Check this:检查这个:

import tkinter as tk


class SelectableText(tk.Text):

    def __init__(self, master, **kwarg):
        super().__init__(master, **kwarg)
        self.down_ind = ''
        self.up_ind = ''
        self.bind("<Control-Button-1>", self.mouse_down)
        self.bind("<B1-Motion>", self.mouse_drag)
        self.bind("<ButtonRelease-1>", self.mouse_up)
        self.bind("<BackSpace>", self.delete_)

    def mouse_down(self, event):
        self.down_ind = self.index(f"@{event.x},{event.y}")

    def mouse_drag(self, event):
        self.up_ind = self.index(f"@{event.x},{event.y}")
        if self.down_ind and self.down_ind != self.up_ind:
            self.tag_add(tk.SEL, self.down_ind, self.up_ind)
            self.tag_add(tk.SEL, self.up_ind, self.down_ind)

    def mouse_up(self, event):
        self.down_ind = ''
        self.up_ind = ''

    def delete_(self, event):
        selected = self.tag_ranges(tk.SEL)
        if len(selected) > 2:
            not_deleting = ''
            for i in range(1, len(selected) - 1):
                if i % 2 == 0:
                    not_deleting += self.get(selected[i-1].string, selected[i].string)
            self.delete(selected[0].string, selected[-1].string)
            self.insert(selected[0].string, not_deleting)
            return "break"


root = tk.Tk()

text = SelectableText(root, width=50, height=10)
text.grid()
text.insert('end', "This is the first line.\nThis is the second line.\nThis is the third line.")

root.mainloop()

So I was trying to delete each selection with the Text.delete(index1, index2) but when the first selection in one line is deleted, the indices changes, making the subsequent delete deleting indices not selected (or out of range in the particular line.所以我试图用Text.delete(index1, index2)删除每个选择,但是当一行中的第一个选择被删除时,索引会发生变化,从而导致后续delete删除索引未被选中(或超出特定行中的范围) .

I had to work around another way - first deleting from the first selected to the last selected, just like what BackSpace would do by default, then put back every unselected part in the middle.我不得不解决另一种方法 - 首先从第一个选择到最后一个选择删除,就像BackSpace默认会执行的操作,然后将每个未选择的部分放回中间。 The Text.tag_ranges gives you a list of ranges selected in this way: Text.tag_ranges为您提供以这种方式选择的范围列表:

[start1, end1, start2, end2, ...]

where each entry is a <textindex object> with a string property (the index).其中每个条目都是具有string属性(索引)的<textindex object> So you can extract the text between end1 and start2 , between end2 and start3 , etc. to the end, and store these into a variable ( not_deleting ) so you can insert them back into the text.因此,您可以提取end1start2之间、 end2start3之间的文本等到最后,并将它们存储到一个变量( not_deleting )中,这样您就可以将它们重新插入到文本中。

There should be better and neater solutions but for now this is what it is... Hope it helps.应该有更好和更整洁的解决方案,但现在就是这样......希望它有所帮助。

Short answer: set the exportselection attribute of each Text widget to False简短回答:将每个 Text 小部件的exportselection属性设置为False

Tkinter gives you control over this behaviour with the exportselection configuration option for the Text widget as well as the Entry and Listbox widgets. Tkinter 让您可以使用 Text 小部件以及 Entry 和 Listbox 小部件的exportselection配置选项来控制此行为。 Setting it to False prevents the export of the selection to the X selection, allowing the widget to retain its selection when a different widget gets focus.将其设置为False可防止将选择导出到 X 选择,从而允许小部件在不同的小部件获得焦点时保留其选择。

For example:例如:

import tkinter as tk
...
text1 = tk.Text(..., exportselection=False)
text2 = tk.Text(..., exportselection=False)

you can find more info here: http://tcl.tk/man/tcl8.5/TkCmd/options.htm#M-exportselection你可以在这里找到更多信息: http://tcl.tk/man/tcl8.5/TkCmd/options.htm#M-exportselection

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM