gpt4 book ai didi

linux - tkinter 复制粘贴到 Entry 不会删除选定的文本

转载 作者:太空狗 更新时间:2023-10-29 11:35:28 25 4
gpt4 key购买 nike

当我复制一些文本并将其粘贴 (crtl + v) 到 tkinter Entry 中时,如果有选定的文本,它不会将其从条目中删除。我在 Linux (Mint) 64 位上。

这里我用 (ctrl + c) 复制“d”: enter image description here

然后我选择“b”: enter image description here

现在我将“d”(ctrl + v)粘贴到它上面,但结果是这样的: enter image description here

首先:我想知道这是 Linux 特有的错误还是应该如此?

第二:我正在考虑使用 validatecommand 解决此问题,但我遇到了另一个问题:

如果我要在命令中删除选定的文本,我必须知道条目中选择的索引。否则,如果在光标前后直接有多个选定文本实例,我将不知道要删除哪一个并用新文本替换。因为光标可能位于所选内容的任一侧(取决于用户是在文本上从右向左还是从左向右拖动鼠标)。

现在有办法获取条目中selectionindex吗?或其他解决此问题的方法?

下面是一些带有问题示例的代码:

import tkinter as tk

root = tk.Tk()

def validation(after_text, before_text, validation_text, cursor_index):
cursor_index = int(cursor_index)
print('cursor index:', cursor_index)
print('text after change:', after_text)
print('text before change:', before_text)
print('text in need of validation:', validation_text)

try:
selection = root.selection_get()
except:
selection = ''
print('selection:', selection)

# EXAMPLE:

# validation_text = 'd'
# before text = "bb"

# now if someone dragged from right to left on the 2nd b:
# cursor position will be 1 (imagine | as the cursor): 'b|b'
# cursor_index = 1
# after_text = 'bdb' --> but should be 'bd'

# now if someone dragged from left to right on the 2nd b:
# cursor position will be 2 (imagine | as the cursor): 'bb|'
# cursor_index = 2
# after_text = 'bbd' --> but should be 'bd'

# so there is no way for me to know which of these b's I have
# to replace with d based on cursor position alone. I have to
# know the index of selection itself in before_text to be
# able to replace the text properly.

# I don't know how to get that.

return True

txtvar = tk.StringVar(value = 'a-b-c-d-e')
entry = tk.Entry(root, textvariable = txtvar)
font = tk.font.Font(family = entry.cget('font'), size = -50)

entry.config(validate = 'all',
vcmd = (root.register(validation),'%P', '%s', '%S', '%i'),
font = font)
entry.pack()

root.mainloop()

最佳答案

这不是错误。如果它是一个错误,十年前就会有人注意到它并修复它。 Tkinter 已经存在很长时间了,像这样的基本事物不会被忽视。

在基于 X11 的系统上实现粘贴不会在粘贴前删除选定的文本。以下是截至我撰写本文时实际的底层 Tcl 代码:

bind Entry <<Paste>> {
global tcl_platform
catch {
if {[tk windowingsystem] ne "x11"} {
catch {
%W delete sel.first sel.last
}
}
%W insert insert [::tk::GetSelection %W CLIPBOARD]
tk::EntrySeeInsert %W
}
}

使用验证功能肯定是解决这个问题的错误方法。 Validation 顾名思义就是:validation。正确的解决方案是创建您自己的绑定(bind)到 <<Paste>>事件。

Now is there a way to get the index of selection in the entry? or another way to workaround this problem?

是的,条目小部件具有特殊索引 sel.first表示选择中的第一个字符,sel.last表示选择后的字符。

将上述代码直接翻译成 python(减去对 x11 的检查)看起来像这样:

def custom_paste(event):
try:
event.widget.delete("sel.first", "sel.last")
except:
pass
event.widget.insert("insert", event.widget.clipboard_get())
return "break"

要将其应用于特定小部件,请绑定(bind)到 <<Paste>>该小部件的事件:

entry = tk.Entry(...)
entry.bind("<<Paste>>", custom_paste)

如果你想做一个适用于每个 Entry 的单一绑定(bind)小部件,使用 bind_class :

root = tk.Tk()
...
root.bind_class("Entry", "<<Paste>>", custom_paste)

关于linux - tkinter 复制粘贴到 Entry 不会删除选定的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46634858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com