gtk 小部件拥有自己的 window 意味着什么

What does it mean for a gtk widget to have its own window

我正在尝试学习 pygtk 并理解文档和教程中术语的含义。

根据文档

  1. 按钮对象没有有自己的window。
  2. 不接收事件的小部件(没有自己的 window 的小部件)将无法使用工具提示。

所以我会得出结论,工具提示不适用于按钮。这似乎是错误的,下面的示例代码似乎证明它是错误的。所以我对这些术语的含义有些不理解?以上说法是否错误?谁能解释我在这里缺少的东西。是不是方法 get_has_window() 没有回答与工具提示是否有效相同的问题?

#!/usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk

class IsButtonNoWindowWidget:
    def sillycallback(self, widget, data):
        print data
        if widget.get_has_window():
            print "Which has a window"
        else:
            print "Which does *not* have a window"

    def __init__(self):
        # create a properly dismissable top level
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("destroy", lambda w: gtk.main_quit())

        button = gtk.Button("PRESS ME")
        button.connect("clicked", self.sillycallback, 
                       "You have clicked the button")
        tooltips = gtk.Tooltips()
        # according to pygtk documentation:
        # Widgets that do not receive events
        # (widgets that do not have their own window)
        # will *not* work with tooltips.
        tooltips.set_tip(button, "just press me, already!")
        self.window.add(button)
        button.show()
        self.window.show()

def main():
    gtk.main()
    return 0

if __name__ == "__main__":
    IsButtonNoWindowWidget()
    main()

我不是 Gtk 内部专家,所以我可能是错的。我怀疑有些混乱...

  • Gtk.Window 是顶层 window,由 window 管理器 'managed' 显示最大化、关闭按钮和程序姓名。

  • Gtk.gdk.window()(根据Gdk/Gtk/Language有不同的名字)是Gdk特有的'window',它为要绘制的小部件,它为按钮按下和按键等事件提供敏感区域。

Gtk.Label 众所周知没有 gdk.window,并且无法捕获此类事件(您必须在其后面放置一个 Gtk.EventBox 才能解决该问题)。

据我所知(我找不到任何其他建议的参考),Gtk.Button 是否有 Gdk.Window,并且按钮的appearance 是在那个window 上画的(当然也可以接收事件)

显示工具提示是 Gtk.Widget 的任务,Gtk.Label 确实派生自 Gtk.Widget(Gtk.Button):

+-- gobject.GObject
  +-- gtk.Object
    +-- gtk.Widget
      +-- gtk.Misc
        +-- gtk.Label

+-- gobject.GObject
  +-- gtk.Object
    +-- gtk.Widget
      +-- gtk.Container
        +-- gtk.Bin
          +-- gtk.Button

因此两者都应该能够显示工具提示,如以下程序所示:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
#  test_label_tooltip.py
#
#  Copyright 2017 John Coppens <john@jcoppens.com>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
#


import gi
gi.require_version('Gtk', '3.0')
gi.require_version('GooCanvas', '2.0')
from gi.repository import Gtk, GooCanvas

class MainWindow(Gtk.Window):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.connect("destroy", lambda x: Gtk.main_quit())

        label = Gtk.Label("This is a label",
                    tooltip_text = "This is the label's tooltip")
        button = Gtk.Label("This is a button",
                    tooltip_text = "This is the button's tooltip")

        vbox = Gtk.VBox()
        vbox.pack_start(label, False, False, 3)
        vbox.pack_start(button, False, False, 3)

        self.add(vbox)
        self.show_all()

    def run(self):
        Gtk.main()


def main(args):
    mainwdw = MainWindow()
    mainwdw.run()

    return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

简而言之:显示工具提示的能力与小部件是否具有 Gdk.Window 无关。事实上,工具提示可以超出顶层 Gtk.Window,我怀疑这表明它有自己的 Gtk.Window 或由 Window 管理器管理(我真的应该调查一下) :