选择从 ttk.Entry 移动到 tkinter.Text
selection moves from ttk.Entry to tkinter.Text
这是一个令我困惑的 python/tkinter 程序。 window 显示只读的 ttk.Entry 和禁用的 tkinter.Text。它以编程方式 select 在输入框中输入一个字符,并且从不更改此 selection。但是,如果我尝试在 other 框(disabledText)中输入 select 文本,selection 将会改变。这似乎不对。
Python 3.5.0 和 tcl/tk 8.5.18 OS X
- 当您 运行 程序时,您可以看到 "A" 在条目(上)框中突出显示。
- 按几次 "Write Data" 按钮; print 语句将在输入框中显示 selected 的 "A"。
- 将鼠标扫过文本(下方)框中的一些文本;不会高亮,但Entry中的高亮会消失
- 按下 "Write Data" 按钮;打印语句将显示您用鼠标扫过的字符。
- 这些字符来自条目上的 selection_get()!你可以看出它是从文本中获取的,因为这两个框没有共同的字符。
如果有人能解释一下,我将不胜感激。
import tkinter
from tkinter import ttk
class ButtonPanel(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.data = ttk.Entry(self, width=27, takefocus=False)
self.data.insert(0, "ABCDEFG")
self.data.select_range(0, 1) # select the "A"
self.data.state(["readonly"])
self.data.bind('<ButtonPress>', lambda e: 'break') # ignore mouse clicks
button = ttk.Button(self, text="Write Data", command=self.master.write)
self.data.grid(column=0, row=0, padx=10)
button.grid(column=1, row=0, padx=10)
def get(self):
return self.data.selection_get() # should always be the "A"
class App(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.bp = ButtonPanel(self)
self.display = tkinter.Text(self, width=50, height=10, wrap="char", takefocus="False")
self.display.insert('end', "HIJKLMNOPQRSTUV")
self.display.config(state="disabled")
self.bp.pack()
self.display.pack()
def write(self):
char = self.bp.get() # should always be the "A"
print("this should be just one character: ->{}<-".format(char))
if __name__ == "__main__":
root = tkinter.Tk()
root.title("What's up here?")
App(root).pack()
root.mainloop()
您观察到的是默认行为。这两个小部件(以及列表框)都有一个名为 exportselection
的属性,默认值为 True
。当 True
时,小部件会将选择导出为主要选择。在旧的 unix 系统(tcl/tk 和 tkinter 开始的地方),你一次只能有一个 "primary" 选择。
简单的解决方案是为文本小部件将此选项设置为 False
。这将允许您的应用程序一次选择多个项目,但只有条目小部件将选择导出到剪贴板(这是 selection_get
工作所必需的。
...
self.display = tkinter.Text(self, ..., exportselection=False)
...
另一个问题是,在 OSX 上,选择不会显示禁用的文本小部件。正在选择文本,您只是看不到它。更准确地说,除非小部件具有焦点,否则不会显示选择,并且默认情况下,当您单击它时它不会获得焦点。
这是一个令我困惑的 python/tkinter 程序。 window 显示只读的 ttk.Entry 和禁用的 tkinter.Text。它以编程方式 select 在输入框中输入一个字符,并且从不更改此 selection。但是,如果我尝试在 other 框(disabledText)中输入 select 文本,selection 将会改变。这似乎不对。
Python 3.5.0 和 tcl/tk 8.5.18 OS X
- 当您 运行 程序时,您可以看到 "A" 在条目(上)框中突出显示。
- 按几次 "Write Data" 按钮; print 语句将在输入框中显示 selected 的 "A"。
- 将鼠标扫过文本(下方)框中的一些文本;不会高亮,但Entry中的高亮会消失
- 按下 "Write Data" 按钮;打印语句将显示您用鼠标扫过的字符。
- 这些字符来自条目上的 selection_get()!你可以看出它是从文本中获取的,因为这两个框没有共同的字符。
如果有人能解释一下,我将不胜感激。
import tkinter
from tkinter import ttk
class ButtonPanel(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.data = ttk.Entry(self, width=27, takefocus=False)
self.data.insert(0, "ABCDEFG")
self.data.select_range(0, 1) # select the "A"
self.data.state(["readonly"])
self.data.bind('<ButtonPress>', lambda e: 'break') # ignore mouse clicks
button = ttk.Button(self, text="Write Data", command=self.master.write)
self.data.grid(column=0, row=0, padx=10)
button.grid(column=1, row=0, padx=10)
def get(self):
return self.data.selection_get() # should always be the "A"
class App(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.bp = ButtonPanel(self)
self.display = tkinter.Text(self, width=50, height=10, wrap="char", takefocus="False")
self.display.insert('end', "HIJKLMNOPQRSTUV")
self.display.config(state="disabled")
self.bp.pack()
self.display.pack()
def write(self):
char = self.bp.get() # should always be the "A"
print("this should be just one character: ->{}<-".format(char))
if __name__ == "__main__":
root = tkinter.Tk()
root.title("What's up here?")
App(root).pack()
root.mainloop()
您观察到的是默认行为。这两个小部件(以及列表框)都有一个名为 exportselection
的属性,默认值为 True
。当 True
时,小部件会将选择导出为主要选择。在旧的 unix 系统(tcl/tk 和 tkinter 开始的地方),你一次只能有一个 "primary" 选择。
简单的解决方案是为文本小部件将此选项设置为 False
。这将允许您的应用程序一次选择多个项目,但只有条目小部件将选择导出到剪贴板(这是 selection_get
工作所必需的。
...
self.display = tkinter.Text(self, ..., exportselection=False)
...
另一个问题是,在 OSX 上,选择不会显示禁用的文本小部件。正在选择文本,您只是看不到它。更准确地说,除非小部件具有焦点,否则不会显示选择,并且默认情况下,当您单击它时它不会获得焦点。