가 나는 Tkinter의 텍스트 위젯이 수정되었는지 여부를 추적 할 this earlier question에서 다음과 같은 솔루션을 사용 : 그러나복사/붙여 넣기시 크래시가 발생하지 않는 프록시를 사용하여 tkinter 텍스트 위젯을 수정했는지 여부를 어떻게 추적합니까?
import tkinter as tk
class CustomText(tk.Text):
def __init__(self, *args, **kwargs):
"""A text widget that report on internal widget commands"""
tk.Text.__init__(self, *args, **kwargs)
# create a proxy for the underlying widget
self._orig = self._w + "_orig"
self.tk.call("rename", self._w, self._orig)
self.tk.createcommand(self._w, self._proxy)
def _proxy(self, command, *args):
cmd = (self._orig, command) + args
result = self.tk.call(cmd)
if command in ("insert", "delete", "replace"):
self.event_generate("<<TextModified>>")
return result
root = tk.Tk()
label = tk.Label(root, anchor="w")
text = CustomText(root, width=40, height=4)
label.pack(side="bottom", fill="x")
text.pack(side="top", fill="both", expand=True)
def onModification(event):
chars = len(event.widget.get("1.0", "end-1c"))
label.configure(text="%s chars" % chars)
text.bind("<<TextModified>>", onModification)
root.mainloop()
, 내 자신의 코드에 통합 한 후, 난 둘 다 내 코드에서이 문제를 위의 베어 해결책을 발견 . 텍스트 위젯에 붙여 넣으려고하면 프로그램 전체가 중단됩니다. 터미널은 다음과 같은 오류 제공합니다. (위의 파일 경로에서 나는 식별 제거 정보하지만, 그렇지 않으면 그 콘솔에서 바로 복사 된)
Traceback (most recent call last):
File "Test.py", line 39, in <module>
root.mainloop()
File "AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 1277, in mainloop
self.tk.mainloop(n)
File "Test.py", line 16, in _proxy
result = self.tk.call(cmd)
_tkinter.TclError: text doesn't contain any characters tagged with "sel"
을 테스트 조금 후
, 당신 밝혀 붙여 넣을 때 텍스트를 선택/강조 표시 한 경우 프로그램을 중단하지 않고 붙여 넣을 수 있습니다.
이 동작은 수정되지 않은 텍스트 위젯에서는 발생하지 않습니다. 텍스트를 선택하지 않고 붙여 넣을 수 있습니다.
내 질문은 어떻게 붙여 넣기가 충돌하지 않도록 위의 솔루션을 수정할 수 있습니까? Tcl/Tk에 익숙하지 않아이 문제를 어떻게 조사해야할지 모르겠습니다. 이것은 Python 3.6.3에 있습니다.
는 (내가 직접이 코드의 원래 저자에 문의 한 것이지만, 거기에는 비공개 메시지 기능은 여기에 없다 내가 새로운 사용자로 덧글을 남길 수 없습니다 밖으로는 변합니다.)편집 : 내가 가진 이제 실제 코드를 해결하는 대신 솔루션이 덕트 테이프와 함께 유지되는 것처럼 느껴지지만 다음과 같이 나는되며 customText 클래스를 변경 :
이return "break"
로 끝나는 함수에
"<<Paste>>"
를 결합함으로써
class CustomText(tk.Text):
def __init__(self, *args, **kwargs):
"""A text widget that report on internal widget commands"""
tk.Text.__init__(self, *args, **kwargs)
# create a proxy for the underlying widget
self._orig = self._w + "_orig"
self.tk.call("rename", self._w, self._orig)
self.tk.createcommand(self._w, self._proxy)
self.bind("<<Paste>>", self.Paste)
def _proxy(self, command, *args):
cmd = (self._orig, command) + args
result = self.tk.call(cmd)
if command in ("insert", "delete", "replace"):
self.event_generate("<<TextModified>>")
return result
def Paste(self, event):
tagranges = self.tag_ranges("sel")
if tagranges:
selectionstart = self.index(tk.SEL_FIRST)
selectionend = self.index(tk.SEL_LAST)
self.delete(selectionstart, selectionend)
self.mark_set(tk.INSERT, selectionstart)
self.insert(tk.INSERT, root.clipboard_get())
self.see(tk.INSERT)
return "break"
, 내가 사고의 원인이 무엇에 따라 이벤트를 통과 위젯을 중지 할 수 있으며, 수정 이벤트는 여전히 화재 예상했다. 즐겁게, 나는 return "break"
선 앞에 내 자신의 붙여 넣기 기능을 코딩 할 수 있으며 처음부터 가지고 있어야한다고 생각하는대로 기능합니다.
Windows 문제 (Bryan Oakley를 확인해 주셔서 감사합니다)를 제외하고는이 문제의 원인을 알 수 없습니다.
코드가 제대로 작동합니다. 텍스트 위젯에 있거나 텍스트 위젯에서 선택한 것과 상관없이 충돌이 발생하지 않습니다. 불행히도 테스트 할 창문 기계가 없습니다. –
처음에는 OS 의존적 인 문제를 넘어서서 어떤 문제가 발생했는지 아직 알지 못했지만 솔직한 솔루션으로 편집했습니다. 봐 주셔서 감사합니다! – Marelo
파이썬 3.6의 Windows 10에서 복제 할 수 있습니다. –