7

私はTkinterとcanvasウィジェットを使用してインターフェースに取り組んでおり、これまでに他の質問や投稿された回答から私が抱えていた問題に対する回答を見つけましたが、これには困惑しています。

GUI要素が作成されるクラスにいくつかのキーボードバインドがあり、プログラムの開始時にそれらはすべて正常に機能します。バインドは次のようになります。

self.canvas.get_tk_widget().bind("<Control-o>",self.flash_open)

クラスの__init__関数内にあります。昨日の時点で、このクラスを初期化してプログラムを開始し、ユーザーがメニューから[開く]を選択するのを待ってから、(とりわけ)tkmessageboxを開きました。

self.specfilename =askopenfilename(filetypes=[("spec", "")],initialdir= self.pathname)

このファイル名を使用すると、特定のファイルタイプから必要な変数名を取得できます(問題には影響しません)。今日、私は__init__関数を変更して、プログラムの起動時にopen関数を呼び出すようにしました。このファイルを開くまで他に何もできないので、最初にファイルを開くのが理にかなっています。ファイルを選択してTkmessageboxを閉じると、ルートウィンドウがアクティブになりますが、キーボードバインドは機能しません。私の関数は、バインドではなく、割り当てられたメニュー/ボタンを使用して引き続き機能します。ショートカットをルートにバインドしようとしましたが、同じ結果になりましたが、呼び出している順序に問題がある可能性があると考えています。

def __init__(self):
    ...
    self.openfile() #calls the tkmessagebox
    self.root.mainloop() #starts gui

私は実際に以前にこの問題に遭遇しました。そこでは、toplevel()インスタンスが閉じられ/破棄され、親ウィンドウのバインドが無効になりました。話すエラーメッセージはありません。バインドは何もしません。また、ルートウィンドウに再び焦点を合わせようとしたことにも言及する必要があります

self.openfile()
self.root.mainloop()
self.root.focus_set()

以前は、wm_withdraw()関数とwm_deiconify()関数を使用して子ウィンドウを非表示にし、プログラムの完了後に閉じることで回避しました。ただし、この場合、この修正を適用するのは少し難しくなります。誰かが問題の原因に光を当てることができれば、私はそれをいただければ幸いです。

編集:

私の問題が何であるかを正確に示すために、実行可能なコードセグメントを作成しました。

import os
from tkFileDialog import askopenfilename
from Tkinter import *


class Start:
    def __init__(self):

        self.root = Tk()
        self.root.title('Binding Troubles')
        menubar = Menu(self.root)
        #add items and their commands to the menubar
        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label="Do work", command=self.do_work)
        filemenu.add_command(label="Open File",command=self.openfile)
        menubar.add_cascade(label="File", menu=filemenu)
        #bind control-o to perform the do work function
        self.root.bind("<Control-o>",self.flash_do_work)
        self.root.bind("<Control-O>",self.flash_do_work)
        #add the menubar to the GUI
        self.root.config(menu=menubar) 
        #initially open a tkdialog to open a file
        self.openfile()#comment out this line to make the bind work 
        self.root.focus()#also tried self.root.focus_set()
        self.root.mainloop()
    def flash_do_work(self,event):
        #indirect tie to the do_work() function, I'm don't know a 
        #proper way to make functions handle calls from both events and non-events
        self.do_work()
    def openfile(self):
        #gets current path
        self.pathname = os.getcwd()
        #Requests filename using a tkdialog
        self.filename =askopenfilename(initialdir= self.pathname)
        print self.filename
    def do_work(self):
        #placeholder for actual function; shows whether the bind is working or not
        print "work"

Start()

self.openfile()が__init __から削除され、メニューからのみ使用される場合、バインドは機能します

別の編集:例を再度更新し、openfile()関数を実行するためのメニューオプションを提供しました。openfile()が__init __で呼び出された場合、バインドが機能しないことに気付きました。ただし、次にopenfile関数が再度呼び出されると、今回はメニューから手動で、バインドが再び機能し始めます。これから何を取るべきか正確にはわかりません。また、投稿が長くなってしまったことをお詫びします。

4

1 に答える 1

5

変化する

self.openfile()

self.root.after(1, self.openfile)

これにより、呼び出しがaskopenfilenameメイン イベント ループに移動します。メインのイベント ループの外に置くと、何らかの形でイベント バインディングが破壊されます。

于 2012-08-02T16:56:14.523 に答える