python tkinter treeview不允许像on_rightclick这样直接绑定的模态窗口 [英] python tkinter treeview not allowing modal window with direct binding like on_rightclick

查看:125
本文介绍了python tkinter treeview不允许像on_rightclick这样直接绑定的模态窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具有鼠标单击绑定的Treeview 直接调用函数以打开模态窗口在grab_set() 上失败

Treeview with mouseclick binding that directly calls a function to open a modal window fails on grab_set()

tkinter.TclError: grab failed: window not viewable

如果鼠标点击首先打开一个调用模态窗口函数的弹出菜单,同样效果很好.

The same works perfectly well if the mouseclick first opens a popup menu that calls the modal window function.

难道不能直接通过鼠标点击(最好是双击)打开模态窗口吗?

Is it not possible to open a modal window directly from a mouseclick (preferably doubleclick)?

Linux Mint 17/Ubuntu 14.04,64 位,Python 3

Linux Mint 17/Ubuntu 14.04, 64bit, Python 3

我的简单代码示例如下.请注意,虽然我调用了两个不同的函数,但每个函数中的代码基本相同.当从弹出菜单调用时,它会提供一个模式窗口,当直接从树视图中调用时,它会失败.这是预期的行为吗?

My simple code example below. Please note that though I call two different functions, the code in each is essentially the same. When called from the popup menu it gives a modal window, when called directly from the treeview, it fails miserably. Is that expected behavior?

import tkinter as tk
from tkinter import ttk

class PopupWindow(tk.Toplevel):
  def __init__(self,parent):
        tk.Toplevel.__init__(self,parent)
        self.parent=parent
        self.protocol("WM_DELETE_WINDOW",self.destroy)
        self.attributes('-topmost',True)
        self.transient()
        mainWindow=tk.Frame(self)
        tFrame=tk.Frame(mainWindow)
        self.tLabel=tk.Label(tFrame,text='Is this modal?',height=3,bd=10)
        self.tLabel.pack()
        self.tLabel2=tk.Label(tFrame,text=' ',height=3,bd=10)
        self.tLabel2.pack()
        bFrame=tk.Frame(mainWindow,bd=5)
        bOK=tk.Button(bFrame,bd=1,text='Ok',command=self.destroy)
        bOK.pack(side='left')
        tFrame.grid(row=0,column=0)
        bFrame.grid(row=1,column=0,sticky=tk.E)
        mainWindow.pack()

class App:
    def __init__(self):
        self.root = tk.Tk()
        self.tree = ttk.Treeview()
        self.tree.pack()
        for i in range(10):
            self.tree.insert("", "end", text="Item %s" % i)
        self.tree.bind("<Double-1>", self.onDoubleClick)
        self.tree.bind("<Button-3>", self.onRightClick)

        self.aMenu = tk.Menu(self.root, tearoff=0)
        self.aMenu.add_command(label="Show 'Modal' Window", 
                command=lambda selection=self.tree.selection(): self.showIsModal(selection))
        self.aMenu.add_separator()

        self.root.mainloop()

    def onRightClick(self, event):
      try:
        self.aMenu.selection = self.tree.identify_row(event.y)
        self.aMenu.post(event.x_root, event.y_root)
      finally:
        self.aMenu.grab_release()

    def showIsModal(self, item):
      pup=PopupWindow(self.root);
      pup.tLabel2['text']="Absolutely!"
      pup.grab_set()
      self.root.wait_window(pup)

    def onDoubleClick(self, event):
        item = self.tree.identify('item',event.x,event.y)
        self.tree.grab_release()
        self.showIsNotModal(item)

   def showIsNotModal(self, item):
      print("you clicked on", self.tree.item(item,"text"))
      pup=PopupWindow(self.root);
      pup.tLabel2['text']="Sadly no: grab_set() fails"
      # following line will fail:
      pup.grab_set()
      self.root.wait_window(pup)


if __name__ == "__main__":
  app = App()

推荐答案

我也使用 Linux Mint 17/Ubuntu 14.04, 64bit, Python 3.

您可以随时检查现有对话框的源代码并了解其工作原理.

You can always check source code of existing dialogs and see how it works.

例如检查 filedialogs - 带有源代码的文件路径:

For example check filedialogs - path to file with source code:

import tkinter.filedialog

print(tkinter.filedialog.__file__)

# /usr/lib/python3.5/tkinter/filedialog.py

你会看到

self.top.wait_visibility() # window needs to be visible for the grab
self.top.grab_set()

所以你必须在 grab_set()

def showIsNotModal(self, item):
    print("you clicked on", self.tree.item(item, "text"))
    pup = PopupWindow(self.root);
    pup.tLabel2['text'] = "Sadly no: grab_set() fails"

    pup.wait_visibility() # <-----

    pup.grab_set()
    self.root.wait_window(pup)

这篇关于python tkinter treeview不允许像on_rightclick这样直接绑定的模态窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆