2011-10-16 14 views
5

エンドユーザがテキストウィジェットのテキストを編集/追加/削除することを抑制する方法は? (Python v3.2 ..とtkinter)python3-tkinterのRead Only Textウィジェット。クロスプラットフォーム

は、テキストを変更/追加/削除する機能のみを抑制しますが、他の機能を拒否することはできません。恐らくNoEdit Textが拡大された方が良い名前になるでしょう。

私はの.text [「状態」]を試してみました=「無効」と、それは、Windowsのほとんど OK (それはまだコピーテキストがページアップ/ダウンとアップ、選択を強調/ユーザが選択することを可能に働きました/下のボタンが機能します。壊れた唯一のものは目に見えないカーソルのようです。)しかし、マッキントッシュではすべてが壊れています。 TkinterにはPythonで事実上何のドキュメントを持っていないので何もハイライト、[いいえ]を選択/コピー、... UGH

は、私が検索されず、いくつかのTCLのアドバイスを発見し、新しいクラスを派生し、挿入を抑制し、削除しました機能。

だから、私はそうと試してみた:

class roText(tk.Text): 
    def insert(self,*args,**kwargs): 
     print(" Hey - Im inside roText.insert") 
     pass 
    def delete(self,*args,**twargs): 
     pass  
    def pInsert(self,*args,**twargs): 
     super().insert(*args,**twargs) 

残念ながら、それが正しく動作しませんでした。明らかにエンドユーザがコードを入力/削除するとき、tkinterはそれらの挿入機能と削除機能を使用しません。おそらくそれらのTCLの挿入/削除は何か他のものであり、私はTCLとスワヒリから何か翻訳を失いました。 tkinter.Textはエンドユーザがテキストを編集するためにどのような機能を使用しますか?うまくいけば、彼らは内部ではありません...

だから、エンドユーザーの編集だけを抑制するためにテキストウィジェットを変更する方法はありますか? 内部のTkinterコード内でダイビングすることなくそれを行う方法があるので、Tkinterの次のリリースでは壊れないでしょうか?

アイドルシェルウィンドウを見ると、編集を抑制していることがわかります(最後の行を除く)。だから道がある。しかし、それは何で、どれくらいの費用がかかりますか?

答えて

2

Macでdisabledの状態が動作しないように見える理由は、ウィジェットにフォーカスを当てているバインディングをオフにするためです。フォーカスがなければ、Macでの強調表示は表示されません。状態をdisabledに設定してから、<ButtonPress-1>にバインディングを割り当てて、無効なテキストウィジェットにフォーカスを明示的に設定すると、テキストを選択してコピーすることができ、ハイライトが表示されます。

カーソルが消えているのは間違いなく、起こりそうなことです。カーソルは、ユーザに「これはテキストが挿入される場所です」と伝えます。テキストが挿入されないので、その視覚的手掛かりがユーザに混乱することになります。カーソルをシミュレートするためにクリックするたびに小さな画像を挿入するのが、本当に重要だった場合は、代わりに行うことができます。

ウィジェットが実際にinsertdeleteメソッドを使用しているかどうかについての質問に答えてください。実際の基礎となるウィジェットのメソッドは、デフォルトのバインディングが使用するものなので、サブクラスでオーバーライドしても効果はありません。そのためには、すべてのデフォルトバインディングをやり直す必要があります。それは可能だが、多くの仕事。

あなた単にウィジェットのinsertdeleteコマンドを無効にすることができますので、残念ながら、これは、Tclのプログラミングは本当に輝いて一つの領域です。もちろん、Tkinterで直接行うこともできます。最終的にはすべてを行うtclコードを実行しますが、これはPythonコーダーの観点からは非常に優れた解決策ではないtclコードを書くことになります。

私は最善の解決策は、あなたがやりたいだけの十分なバインディングを中に追加し、無効状態を使用することだと思います。

は、ここで明示的にマウスボタンのクリックにフォーカスを設定することで動作し、簡単な例を示します。それは私が持っているので、あなたの提案をテストするために私にしばらく時間がかかった@BryanOakley

import Tkinter as tk 

class SampleApp(tk.Tk): 
    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 
     self.text = tk.Text(width=40, height=20) 
     self.text.bind("<1>", self.set_focus) 
     self.text.insert("end", "\n".join(dir(tk.Tk))) 
     self.text.configure(state="disabled") 
     self.text.pack(fill="both", expand=True) 

    def set_focus(self, event): 
     '''Explicitly set focus, so user can select and copy text''' 
     self.text.focus_set() 

if __name__ == "__main__": 
    app = SampleApp() 
    app.mainloop() 
+0

OK、私はMacでテストするチャンスがありました。あなたが言ったように、<1>にバインドされたtext.focus_set()が問題を修正しました。 **ありがとう!!! **(おそらく、このページは解決策を探している人たちのためにクリーンアップすることができます。 残念ながら私は恐らくTkinterをMacに移植すると多くの問題の1つになっていたようだ。 '緑色'の色はボタンでは機能しません。ボタン上のテキストには間隔(これは解像度に関連する可能性があります)などが必要です。これらは回避するのが簡単で、悪化することはありません。 – Momus

-1

:このコードで、私はクリックして、スワイプ地域を選択するか、ダブルまたは単語や行を選択するトリプルクリックすることができますよMacはありません。 残念ながら、MacのPython実装はバグです。 私は今最初に呼び出して、私はウィンドウを作成し、テキストを挿入した後呼び出して、私の無効化機能、つまり、フォーカスを追加しました:

self.txt['state'] = 'disabled' 

、その後

self.txt.focus_set() 

私はあなたがたと思うものですどの提案する。

それ働いた "のようなもの"。つまり、テキストを選択(クリック&ドラッグまたはダブルクリック)すると、強調表示が動作しますほとんどの時間はです。 Pythonには、メモリ参照やそのようなバグがある必要があります。最初は強調表示が機能しない場合があります。クリックした後で同じウィンドウで作業を開始することがあります。時にはプログラムが呼び出されると、バットの右に働きます。 Shift-rightArrowキーで選択すると機能しますが、マウスで選択すると機能しません。その後、再び作業を開始します。それとも、1つのウィンドウで正常に動作しますが、別のもの(同じクラスの両方)で、その後、すべてのウィンドウで作業を開始していない...など...

良いことは、フォーカスを追加するとひどくのWindowsに影響を与えなかったということです(つまり、すべての機能がうまく動作しない場合) Mac用のPythonの将来/次回のリリースでこれらのバグが修正されることを願っています。

ところで、Macは孤児Pythonのための実装は、Windowsにとって非常に醜いです。つまり、フォントが悪くなったり、ボタンが見えたりすることがあります。または、異なる解像度とPythonポートが原因である可能性があります。 Macに焦点を当てていただきありがとうございます。

+0

ウィジェットを作成するときだけでなく、 '<1>'イベントのコールバックで 'focus_set'を呼び出すことができます。あなたの答えから、あなたはフォーカスを一度しか設定していないように見えます。私は繰り返す:ハイライトを表示するには、ウィジェットがフォーカスを持っている必要があります。フォーカスを与えると、他の場所をクリックするたびにフォーカスが失われる可能性があります。フォーカスを設定するために '<1>'へのバインディングを追加すると、選択をしようとするとフォーカスが常に確実になります(選択は常にマウスのクリックから始まるため)。 –

+0

@BryanOakley「<1>イベントのコールバック」という意味がわかりません。私の推測は間違っていたようだ... 私の次の推測では、テキストガジェットのシングルクリックをコールバック関数にバインドすることをお勧めします... txt.focus_set() おそらくダブルクリック(tkinterにがまだチェックされていない場合)>今、私はのバインド/コールバックしか持っていませんが、もちろんこれに対しては特別なバインディングと1行のコールバックをfocus_set()で行うことができます。試して "Macクライアント"に送ってテストします...もう一度ありがとう。 – Momus

+0

私の元の答えは、 "無効なテキストウィジェットにフォーカスを明示的に設定するためにバインディングをに割り当てる"と述べています。私はそれがはっきりしていると思ったが、明らかにそうではなかった。明確にするための例を追加しました。また、ダブルクリックまたはトリプルクリックを行う唯一の方法は、最初にシングルクリックを行うことなので、ダブルクリックまたはトリプルクリックで同じ操作を行う必要はありません。このソリューションでは、またはトリプルクリックして単語や線を選択し、クリックしてドラッグして領域を選択します。 –

2
古い質問をぶつけて申し訳ありません

が、私はこの質問への答えを探していたにも、最終的に解決策を見つけました。私が見つけた解決策は、テキストウィジェットがフォーカスを持っていて非常にシンプルなときにキーバインディングをオーバーライドすることです。 Found here

ウィジェットのバインディングを上書きするには、あなたが上書きされるものの文字列を、あなたはそれを呼び出すようにする新しい関数を渡すバインド機能があります。

クラス内の他の場所では、イベントを処理する関数を定義する必要があります。

def empty(self, event): 
     return "break" 

イベントハンドラは、文字列 "break"を返すことで、デフォルトアクションを続行する代わりに、関数の後で停止することがわかります。

これがあなたの質問に答えることを願っています。乾杯。

関連する問題