2017-06-23 8 views
0

私は、ボタンを押してノートを切り替えることができるプログラムを持っているノートを持っています。これは私のために便利です。私は、テキストボックスにアクティブなノートがあるときに、そのテキストボックスの中でキーボードの任意のキーを押してから別のグループのノートを選択しようとすると、節約する。キー押下を検出するのではなく、TextBoxが編集されたことを検出していますか?

これはうまくいきますが、キーを押すのではなく、ノートが変更されたかどうかを検出する方法を見つける必要があります。この理由は、ポップアップ警告を引き起こすイベントを動かすことなく、私のメモのセクションをコピーするのに"CTRL-C"を使用することができません。テキストボックス内のテキストが編集されていない限り、ノートのグループから別のグループにジャンプすることができます。

"CTRL-C"で強調表示しているテキストをコピーしようとすると、ノートを切り替えると、切り替えたいかどうかを確認するメッセージが表示されます。私はこれを避けようとしており、テキストボックス内にkeypressを検出するのではなく、変更があったかどうかをチェックする方法があるはずです。

textvariabletrackと使用しようとしましたが、テキストボックスにはそのオプションを使用できないようです。

以下は、テキストボックスに入力する方法と、別の一連のメモを開くことを選択すると、続行するかどうかを尋ねる簡単な例です。

from tkinter import * 
from tkinter import messagebox 

class MiniApp(Frame): 
    def __init__(self, master, *args, **kwargs): 
     Frame.__init__(self, master, *args, **kwargs) 
     self.master = master 
     self.text_is_edited = False 

     self.add_text = Button(self.master, text = "Add text to TextBox", command = self.add_to_text) 
     self.add_text.grid(row = 0, column = 0, sticky = "we") 
     self.add_text = Button(self.master, text = "Add text to TextBox", command = self.add_to_text_2) 
     self.add_text.grid(row = 0, column = 1, sticky = "we") 
     self.text = Text(self.master, width = 35, height = 3) 
     self.text.grid(row = 1, column = 0, columnspan = 2, sticky = "nsew") 
     self.text.bind('<Key>', self.is_text_edited) 

    def add_to_text(self): 
     if self.text_is_edited == False: 
      self.text.delete(1.0, "end-1c") 
      self.text.insert("end-1c", "Some other text to work with.\nMore text.") 
      self.text.see("end-1c") 
     else: 
      answer = messagebox.askquestion("Update TextBox", 
        "Are you sure you want change the content of the TextBox? Any unsaved changed will be lost!") 
      if answer == "yes": 
       self.text.delete(1.0, "end-1c") 
       self.text.insert("end-1c", "Some other text to work with.\nMore text.") 
       self.text.see("end-1c") 
       self.text_is_edited = False 

    def add_to_text_2(self): 
     if self.text_is_edited == False: 
      self.text.delete(1.0, "end-1c") 
      self.text.insert("end-1c", "Text to test with.\nMore text.") 
      self.text.see("end-1c") 
     else: 
      answer = messagebox.askquestion("Update TextBox", 
        "Are you sure you want change the content of the TextBox? Any unsaved changed will be lost!") 
      if answer == "yes": 
       self.text.delete(1.0, "end-1c") 
       self.text.insert("end-1c", "Text to test with.\nMore text.") 
       self.text.see("end-1c") 
       self.text_is_edited = False 

    def is_text_edited(self, *args): 
     if self.text_is_edited == False: 
      self.text_is_edited = True 

if __name__ == "__main__": 
    root = Tk() 
    app = MiniApp(root) 
    root.mainloop() 

答えて

2

テキストウィジェットは、変更されているかどうかを追跡します。 edit_modifiedメソッドを呼び出すと、いつでも状態を照会できます。 TrueまたはFalseを返します。必要に応じて、通常はコードを使用してテキストを挿入した後に、同じ方法でフラグをリセットすることができます。

ウィジェットが編集されるたびに、このフラグはtrueに設定されます。したがって、プログラムでテキストを挿入するときは、このフラグをFalseにリセットする必要があります。例えば

:あなたは<<Modified>>イベントを探している

def add_to_text(self): 

    # ask the widget if it has been modified 
    if self.text.edit_modified(): 

     answer = messagebox.askquestion("Update TextBox", 
       "Are you sure you want change the content of the TextBox? Any unsaved changed will be lost!") 
     if answer != "yes": 
      return 

    self.text.delete(1.0, "end-1c") 
    self.text.insert("end-1c", "Some other text to work with.\nMore text.") 
    self.text.see("end-1c") 

    # reset the flag to false. If the user modifies the widget the flag 
    # will become True again 
    self.text.edit_modified(False) 
+0

ありがとうブライアン。それは完璧に働いた。私はこれで、ファイルが編集されている場合に保存を扱う他の機能も簡単にすることができると思います。 –

+0

@SierraMountainTech:フラグが変更されるたびにコールバックが必要な場合は、 '<>'仮想イベントにバインドすることもできます。 –

+0

'<>'イベントを 'self.text.edit_modified(False)'のようにリセットする方法はありますか?本当にあなたの答えは私がこの仕事をするために必要なものでした。 'edit_modified()'ステータスを変更することなく、テキストフィールドから日付をコピーできるようになりました。それが私のプログラムの大きなハングアップでした。 –

2

しかし、テキストウィジェットが変更されたフラグ自体を保持するので、気にする必要はありません。ここでは(あまりにも多くの他のコードの提案を)例を示します

# wildcard imports are bad and lead to bugs. Use proper imports. 
import tkinter as tk 
from tkinter import messagebox 

TEXT1 = "Some other text to work with.\nMore text." 
TEXT2 = "Text to test with.\nMore text." 

class MiniApp(tk.Frame): 
    def __init__(self, master, **kwargs): # there will never be any positional arguments, you don't need *args 
     tk.Frame.__init__(self, master, **kwargs) 
     # self.master = master # this line is built into tkinter widgets; you don't need to repeat it 

     # all widgets should use the Frame as master, not the root window 
     self.add_text = tk.Button(self, text = "Add text to TextBox", command = lambda: self.add_to_text(TEXT1)) 
     self.add_text.grid(row = 0, column = 0, sticky = "we") 
     self.add_text = tk.Button(self, text = "Add text to TextBox", command = lambda: self.add_to_text(TEXT2)) 
     self.add_text.grid(row = 0, column = 1, sticky = "we") 
     self.text = tk.Text(self, width = 35, height = 3) 
     self.text.grid(row = 1, column = 0, columnspan = 2, sticky = "nsew") 

    def add_to_text(self, text): 
     # don't copy/paste code. Use the computer to do repetitive things for you. 
     if self.text.edit_modified() and not messagebox.askyesno("Update TextBox", 
        "Are you sure you want change the content of the TextBox? Any unsaved changed will be lost!"): 
      return # abort!! 

     self.text.delete(1.0, tk.END) # this is a modification and will set the modified flag 
     self.text.insert(1.0, text) 
     self.text.see(tk.END) 
     self.text.edit_modified(False) # reset the modified flag to False 

if __name__ == "__main__": 
    root = tk.Tk() 
    app = MiniApp(root) 
    app.pack() 
    root.mainloop() 

編集:くそブライアンは再び私を破りました。

+0

返信いただきありがとうございます。しかし、ブライアンはそれにあなたを打ち負かす:D。小説を心配しないでください。彼は私をパンチによくぶつけます。 –

+0

ところで、Textウィジェットはあなたが興味を持っているかもしれない元に戻す/やり直しスタックでも焼いてきました。それについては、[公式文書](http://www.tcl.tk/man/tcl/TkCmd/)で知ることができます。 text.htm)。 Pythonのバインディングは 'edit_undo()'と 'edit_redo()'です。 – Novel

+0

私はすでに 'undo = True'を使っていますが、私は' edit_undo() 'と' edit_redo() 'を調べていません。私は一見をありがとう。 –

関連する問題