【问题标题】:python/tkinter popup window appears fine on windows or linux but not on OSX Mojave. NO ERRORSpython/tkinter 弹出窗口在 windows 或 linux 上显示正常,但在 OSX Mojave 上不显示。没有错误
【发布时间】:2019-10-25 23:51:14
【问题描述】:

“我正在从“GUI Programming Cookbook”中学习 Tkinter。使用我的 MacBook Pro 运行 Mojave、python3.8 和打包的 Tkinter。有一种方法可以在鼠标悬停时显示弹出工具提示一个小部件。它在 Win 10 和 linux 上运行良好,但弹出窗口没有出现在我的 Mac 上。没有错误。

我输入了一些调试 print() 语句,鼠标坐标和移动都是正确的。

这行得通****。窗口文本悬停在小部件上

这里是 linux 上 print(sys.version) 的输出。

3.7.4(默认,2019 年 7 月 9 日,16:48:28) [GCC 8.3.1 20190223(红帽 8.3.1-2)]

这不起作用 **** 弹出窗口不出现

Mac 上 print(sys.version) 的输出

3.8.0(v3.8.0:fa919fdf25,2019 年 10 月 14 日,10:23:27) [Clang 6.0 (clang-600.0.57)]

====================

'''
Created on May 3, 2019

@author: Burkhard A. Meier
'''
#======================
# imports
#======================
import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext
from tkinter import Menu
from tkinter import messagebox as msg
from tkinter import Spinbox


        #====================================================
class ToolTip(object):
    def __init__(self, widget, tip_text=None):
        self.widget = widget
        self.tip_text = tip_text
        widget.bind('<Enter>', self.mouse_enter) 
          # bind mouse events
        widget.bind('<Leave>', self.mouse_leave)

    def mouse_enter(self, _event):
        self.show_tooltip()
        print('entered the widget')

    def mouse_leave(self, _event):
        self.hide_tooltip()
        print('entered the widget')

    def show_tooltip(self):
        if self.tip_text:
            x_left = self.widget.winfo_rootx()
                # get widget top-left coordinates
            y_top = self.widget.winfo_rooty() - 18  
            
            #DEBUG
            print('self.widget, y_top, x_left')
            print(self.widget, y_top, x_left)
            
            # place tooltip above widget or it flickers

            self.tip_window = tk.Toplevel(self.widget)   
           # create Toplevel window; parent=widget
            self.tip_window.overrideredirect(True)     
            # remove surrounding toolbar window
            self.tip_window.geometry("+%d+%d" % (x_left, y_top)) 
            # position tooltip

            #print('\nTOOLTIP before author code line')
            #print(self.tip_text)
            #label = tk.Label(self.tip_window, text=self.tip_text,
             #justify=tk.LEFT, background="#ffffe0",
             # relief=tk.SOLID,
             #borderwidth=1, font=("tahoma", "8", "normal"))

            #below is my code cus the above line does 
            #not show up EKK 10/25/19

            label = tk.Label(self.tip_window, text=self.tip_text,
             justify=tk.LEFT)
            label.pack(fill="both")
            #label.pack(ipadx=1)

            print('TOOLTIP after author code line')
            print(self.tip_text)

    def hide_tooltip(self):
        if self.tip_window:
            self.tip_window.destroy()

#=====================================================
# just added all the code.
# the above class is called by the Spinbox and Scroll methods below.

          # Create instance
win = tk.Tk()   
    
# Add a title       
win.title("Python GUI")  
    
tabControl = ttk.Notebook(win)          # Create Tab Control
    
tab1 = ttk.Frame(tabControl)            # Create a tab 
tabControl.add(tab1, text='Tab 1')      # Add the tab
tab2 = ttk.Frame(tabControl)            # Add a second tab
tabControl.add(tab2, text='Tab 2')      # Make second tab visible
    
tabControl.pack(expand=1, fill="both")  # Pack to make visible
    
# LabelFrame using tab1 as the parent
mighty = ttk.LabelFrame(tab1, text=' Mighty Python ')
mighty.grid(column=0, row=0, padx=8, pady=4)
    
# Modify adding a Label using mighty as the parent instead of win
a_label = ttk.Label(mighty, text="Enter a name:")
a_label.grid(column=0, row=0, sticky='W')
    
# Modified Button Click Function
def click_me(): 
    action.configure(text='Hello ' + name.get() + ' ' + 
                     number_chosen.get())
    
# Adding a Textbox Entry widget
name = tk.StringVar()
name_entered = ttk.Entry(mighty, width=12, textvariable=name)
name_entered.grid(column=0, row=1, sticky='W')               
# align left/West
    
# Adding a Button
action = ttk.Button(mighty, text="Click Me!", command=click_me)   
action.grid(column=2, row=1)                                
    
ttk.Label(mighty, text="Choose a number:").grid(column=1, row=0)
number = tk.StringVar()
number_chosen = ttk.Combobox(mighty, width=12, textvariable=number, state='readonly')
number_chosen['values'] = (1, 2, 4, 42, 100)
number_chosen.grid(column=1, row=1)
number_chosen.current(0)
    
# Spinbox callback 
def _spin():
    value = spin.get()
    print(value)
    scrol.insert(tk.INSERT, value + '\n')
         
# Adding a Spinbox widget
spin = Spinbox(mighty, values=(1, 2, 4, 42, 100), width=5, bd=9, command=_spin) 
# using range
spin.grid(column=0, row=2)
   
    # Add a Tooltip to the Spinbox
ToolTip(spin, 'This is a Spin control')
     
# Using a scrolled Text control    
scrol_w  = 30
scrol_h  =  3
scrol = scrolledtext.ScrolledText(mighty, width=scrol_w, height=scrol_h, wrap=tk.WORD)
scrol.grid(column=0, row=3, sticky='WE', columnspan=3)                    
    
# Add a Tooltip to the ScrolledText widget 
ToolTip(scrol, 'This is a ScrolledText widget') 
   
# Bunch of code snipped here

name_entered.focus()      # Place cursor into name Entry
#======================
# Start GUI
#======================
win.mainloop()
    

该类是从其他代码调用的。第 42 行和第 46 行的标签不会出现在我的 MacBook 上,但在 Windows 和 Linux 上一切正常。没有错误消息。窗口永远不会出现。有人有建议吗??我要疯了!提前致谢。

【问题讨论】:

  • 这里是在代码中的enter和leave函数中加入print语句后到终端窗口的输出;作者代码行后的 TOOLTIP 这是一个 ScrolledText 小部件进入小部件离开小部件
  • 我刚刚从 staging python.org 中找到了一些东西。 --- 说使用 Active State。我现在正在研究。
  • 下一次检查:print(self.widget, y_top, x_left) 之后 if self.tip_text:。阅读overrideredirect-prevents-certain-events-in-mac-and-linux
  • 打印输出 =====。 self.widget, y_top, x_left .!notebook.!frame.!labelframe.!frame 263 163. 如果我移动窗口,坐标会跟随 - 所以它知道文本已通过
  • 我走了,最后一想,把你的__main__,从# Create instance 行开始放到if __name__ == "__main__" : 块中。阅读executing-modules-as-scripts

标签: python macos tkinter tk


【解决方案1】:

如果你在 Mac OSX 上仍然遇到这个问题,我发现一个 reddit thread 指向:

https://github.com/python/cpython/blob/master/Lib/idlelib/tooltip.py

我在show_tooltip() 的末尾添加了以下两行:

tw.update_idletasks()  # Needed on MacOS -- see #34275.
tw.lift()  # work around bug in Tk 8.5.18+ (issue #24570)

工具提示开始出现。

【讨论】:

  • 使用tw.update() 而不是tw.update_idletasks(),有时在mainloop() 之前使用tw.lift() 也可以。有多种方法可以解决此问题,请参阅post
  • tw 指的是什么?
  • @ViniDalvino tw 指的是:github.com/python/cpython/blob/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多