2016-05-25 33 views
1

Gtk3でTreeView gtk2ツールチップを翻訳しました ほとんど実行されていますが、ツールチップウィンドウの座標を管理するのに問題があります。gtk3の絶対座標ウィンドウの管理方法python

私はツールチップウィンドウをマウスのそばに配置し、それに続いてください。代わりにツールチップウィンドウが画面の隅に位置している私のプロジェクトの

私のコードは、ツリービューでの相対座標でツールチップを置くために私をelemnt与えることができる

#!/usr/bin/env python 
# coding: utf-8 


''' 
warning data not update !!!!!!!!!!!!! 
TreeViewTooltips.py 

Provides TreeViewTooltips, a class which presents tooltips for cells, 
columns and rows in a Gtk.TreeView. 

------------------------------------------------------------ 
    This file includes a demo. Just execute the file: 

     python TreeViewTooltips.py 
------------------------------------------------------------ 

To use, first subclass TreeViewTooltips and implement the get_tooltip() 
method; see below. Then add any number of Gtk.TreeVew widgets to a 
TreeViewTooltips instance by calling the add_view() method. Overview 
of the steps: 

    # 1. subclass TreeViewTooltips 
    class MyTooltips(TreeViewTooltips): 

     # 2. overriding get_tooltip() 
     def get_tooltip(...): 
      ... 

    # 3. create an instance 
    mytips = MyTooltips() 

    # 4. Build up your Gtk.TreeView. 
    myview = Gtk.TreeView() 
    ...# create columns, set the model, etc. 

    # 5. Add the view to the tooltips 
    mytips.add_view(myview) 

How it works: the add_view() method connects the TreeView to the 
"motion-notify" event with the callback set to a private method. 
Whenever the mouse moves across the TreeView the callback will call 
get_tooltip() with the following arguments: 

    get_tooltip(view, column, path) 

where, 

    view: the Gtk.TreeView instance. 
    column: the Gtk.TreeViewColumn instance that the mouse is 
      currently over. 
    path: the path to the row that the mouse is currently over. 

Based on whether or not column and path are checked for specific 
values, get_tooltip can return tooltips for a cell, column, row or the 
whole view: 

    Column Checked  Path Checked  Tooltip For... 
      Y     Y    cell 
      Y     N    column 
      N     Y    row 
      N     N    view 

get_tooltip() should return None if no tooltip should be displayed. 
Otherwise the return value will be coerced to a string (with the str() 
builtin) and stripped; if non-empty, the result will be displayed as 
the tooltip. By default, the tooltip popup window will be displayed 
centered and just below the pointer and will remain shown until the 
pointer leaves the cell (or column, or row, or view, depending on how 
get_tooltip() is implemented). 

''' 


from gi.repository import Gtk 

class TreeViewTooltips_gtk3: 
    """tooltip atttach to Treeview in Gtk3 
    this window is moving to follow row of Treeview""" 
    def __init__(self): 
     self.win = Gtk.Window() 
     self.win.set_decorated(False) 
     self.win.set_default_size(-1, -1) 
     self.label = Gtk.Label() 
     self.win.add(self.label) 
     # by default, the tooltip is enabled 
     self.__enabled = True   

    def __show(self, tooltip, x, y): 
     """in order to move the tooltip near row of Treeview""" 
     self.label.set_markup(tooltip) 
     w,h = self.win.get_preferred_width() 
     # move the window 
     self.win.move(*self.location(x,y,w,h)) 
     # show it 
     self.win.show_all()  
     return self.win 

    def __leave_handler(self, view, event): 
     """when the pointer leaves the view, hide the tooltip"""   
     self.win.hide() 

    def enable(self): 
     'Enable the tooltip' 
     self.__enabled = True 

    def disable(self): 
     'Disable the tooltip' 
     self.__enabled = False   


    def location(self, x, y, w, h): 
     '''Given the x,y coordinates of the pointer and the width and 
     height (w,h) demensions of the tooltip window, return the x, y 
     coordinates of the tooltip window. 

     The default location is to center the window on the pointer 
     and 4 pixels below it. 
     # en clair c'est un décalage de position de la fenetre qui s'ouvre qui donne l'info 
     ''' 
     return x - w/2, y + 4 

    def tooltip_callback(self,treeview, x, y, keyboard_mode, tooltip): 
     """ in order to collect miscellaneous elemnt to build data with row of treeview""" 
     """3eme règle implementer ça pour afficher un tooltip customisé en fonction des data du tree view""" 
     x, y = treeview.convert_widget_to_bin_window_coords(x, y) 
     if not self.__enabled : 
      """if you don't want tooltip display just return False !!!!""" 
      return False 
     try: 
      path, column, cell_x, cell_y = treeview.get_path_at_pos(x, y) 
      iter = model.get_iter(path) 
      #print 'tooltip=',self.get_tooltip(column, self.cust_col,path) 
      treeview.set_tooltip_window(self.__show(self.get_tooltip(column, self.cust_col,path),x,y)) 
      # necessary to return True in order to display window tooltip 
      print "path is valid :-)" 
      return True 
     except: 
      # to prevent case when path it's not valid 
      print "perhaps path it's not valid ????" 
      # not possible to display something 
      return False  

    def add_view(self, view): 
     """add a Gtk.TreeView to the tooltip 
     check if view is instance of Gtk.TreeView 
     and build connector and tooltip enable""" 
     assert isinstance(view, Gtk.TreeView), \ 
       ('This handler should only be connected to ' 
       'instances of Gtk.TreeView') 
     # first condition in gtk3 
     # set True the property "has-tooltip"   
     view.set_property("has-tooltip", True)  
     # second condition in gtk3 
     view.connect('query-tooltip',self.tooltip_callback) 
     # hide tooltip when mouse out of widget 
     view.connect("leave-notify-event", self.__leave_handler) 

    def get_tooltip(self, view, column, path): 
     """in order to secure customized implementation in your projet""" 
     'See the module doc string for a description of this method' 

     raise NotImplemented, 'Subclass must implement get_tooltip()' 

if __name__ == '__main__': 


    class DemoTips_Gtk3(TreeViewTooltips_gtk3): 
     """demo play how to """ 
     def __init__(self, customer_column): 
      """ 
      init class 
      customer_column is an instance of Gtk.TreeViewColumn and 
      is being used in the Gtk.TreeView to show customer names.""" 
      self.cust_col = customer_column 
      # call base class init 
      TreeViewTooltips_gtk3.__init__(self) 

     def get_tooltip(self, column,cust_col,path): 
      """By checking both column and path we have a cell-based tooltip"""  
      model = view.get_model() 
      customer = model[path][2]  
      if column is cust_col: 
       """here there is lot of information on row""" 
       return '<big>%s %s</big>\n<i>%s</i>' % (customer.fname, 
                 customer.lname, 
                 customer.notes) 
      else: 
       """here basic data only !!!!""" 
       return ('<big><u>Generic Column Tooltip</u></big>\n' 
         'Unless otherwise noted, all\n phone number is %s ') % customer.phone 


    # Here's our customer 
    class Customer: 

     def __init__(self, fname, lname, phone, notes): 
      self.fname = fname 
      self.lname = lname 
      self.phone = phone 
      self.notes = notes 


    # create a bunch of customers 
    customers = [] 
    for fname, lname, phone, notes in [ 
     ('Joe', 'Schmoe', '555-1212', 'Likes to Morris dance.'), 
     ('Jane', 'Doe', '555-2323', 
     'Wonders what the hell\nMorris dancing is.'), 
     ('Phred', 'Phantastic', '900-555-1212', 'Dreams of Betty.'), 
     ('Betty', 'Boop', '555-3434', 'Dreams in b&amp;w.'), 
     ('Red Sox', 'Fan', '555-4545', 
     "Still livin' 2004!\nEspecially after 2006.")]: 
     customers.append(Customer(fname, lname, phone, notes)) 



    # Build our model and view 
    model = Gtk.ListStore(str, str, object) 
    for c in customers: 
     model.append(['%s %s' % (c.fname, c.lname), c.phone, c]) 

    view = Gtk.TreeView(model) 

    # two columns, name and phone 
    cell = Gtk.CellRendererText() 
    cell.set_property('xpad', 20) 
    namecol = Gtk.TreeViewColumn('Customer Name', cell, text=0) 
    namecol.set_min_width(200) 
    view.append_column(namecol) 

    cell = Gtk.CellRendererText() 
    phonecol = Gtk.TreeViewColumn('Phone', cell, text=1) 
    view.append_column(phonecol) 

    # finally, connect the tooltip, specifying the name column as the 
    # column we want the tooltip to popup over. 
    tips = DemoTips_Gtk3(namecol) 
    tips.add_view(view) 

    # We're going to demonstrate enable/disable. First we need a 
    # callback function to connect to the toggled signal. 
    def toggle(button): 
     if button.get_active(): 
      tips.disable() 
     else: 
      tips.enable() 

    # create a checkbutton and connect our handler 
    check = Gtk.CheckButton('Check to disable view tooltips') 
    check.connect('toggled', toggle) 


    check.set_tooltip_markup('This is a standard Gtk tooltip.\n' 
         'Compare me to the tooltips above.') 

    # create a VBox to pack the view and checkbutton 
    vbox = Gtk.VBox() 
    vbox.pack_start(view,False,False,2) 
    vbox.pack_start(check,False,False,2) 
    vbox.show_all() 

    # pack the vbox into a simple dialog and run it 
    dialog = Gtk.Dialog('TreeViewTooltips Demo') 
    close = dialog.add_button(Gtk.STOCK_CLOSE,Gtk.ResponseType.NONE) 
    # add a tooltip for the close button 
    close.set_tooltip_markup('Click to end the demo.') 

    dialog.set_default_size(400,400) 
    dialog.vbox.pack_start(vbox,False,False,2) 
    dialog.run() 

はありますか? 事前に感謝します 私の悪い英語を謝っています

答えて

0

あなたはローカル座標で作業していますので、ダイアログの位置を参照してルート座標を取得する必要があります。あなたのスクリプトの別の問題は、メインウィンドウがダイアログであるため、フォアグラウンドでツールチップがその下に表示されていることです(私はそれを修正しましたがコードを削除しました。 。一般的な注意として、ルート座標が必要な場合は、すべてのウィジェットがその親を参照することを知っていることが良いです。

#!/usr/bin/env python 
# coding: utf-8 

from gi.repository import Gtk 

class TreeViewTooltips_gtk3: 
    """tooltip atttach to Treeview in Gtk3 
    this window is moving to follow row of Treeview""" 
    def __init__(self): 
     self.win = Gtk.Window() 
     self.win.set_decorated(False) 
     self.win.set_default_size(-1, -1) 
     self.label = Gtk.Label() 
     self.win.add(self.label) 
     # by default, the tooltip is enabled 
     self.__enabled = True   

    def __show(self, tooltip, x, y): 
     """in order to move the tooltip near row of Treeview""" 
     self.label.set_markup(tooltip) 
     w,h = self.win.get_preferred_width() 
     # move the window 
     self.win.move(*self.location(x,y,w,h)) 
     # show it 
     self.win.show_all()  
     return self.win 

    def __leave_handler(self, view, event): 
     """when the pointer leaves the view, hide the tooltip"""   
     self.win.hide() 

    def enable(self): 
     'Enable the tooltip' 
     self.__enabled = True 

    def disable(self): 
     'Disable the tooltip' 
     self.__enabled = False   


    def location(self, x, y, w, h): 
     '''Given the x,y coordinates of the pointer and the width and 
     height (w,h) demensions of the tooltip window, return the x, y 
     coordinates of the tooltip window. 

     The default location is to center the window on the pointer 
     and 4 pixels below it. 
     # en clair c'est un décalage de position de la fenetre qui s'ouvre qui donne l'info 
     ''' 
     return x - w/2, y + 4 

    def tooltip_callback(self,treeview, x, y, keyboard_mode, tooltip): 
     """ in order to collect miscellaneous elemnt to build data with row of treeview""" 
     """3eme règle implementer ça pour afficher un tooltip customisé en fonction des data du tree view""" 
     root_x, root_y = self.dialog.get_position() #get the root coordinates 
     x, y = treeview.convert_widget_to_bin_window_coords(x, y) 
     if not self.__enabled : 
      """if you don't want tooltip display just return False !!!!""" 
      return False 
     try: 
      path, column, cell_x, cell_y = treeview.get_path_at_pos(x, y) 
      iter = model.get_iter(path) 
      #print 'tooltip=',self.get_tooltip(column, self.cust_col,path) 
      #add the root coordinates to local coordinates 
      treeview.set_tooltip_window(self.__show(self.get_tooltip(column, self.cust_col,path),root_x+x,root_y+y)) 
      # necessary to return True in order to display window tooltip 
      print("path is valid :-)") 
      return True 
     except: 
      # to prevent case when path it's not valid 
      print("perhaps path it's not valid ????") 
      # not possible to display something 
      return False  

    def add_view(self, view): 
     """add a Gtk.TreeView to the tooltip 
     check if view is instance of Gtk.TreeView 
     and build connector and tooltip enable""" 
     assert isinstance(view, Gtk.TreeView), \ 
       ('This handler should only be connected to ' 
       'instances of Gtk.TreeView') 
     # first condition in gtk3 
     # set True the property "has-tooltip"   
     view.set_property("has-tooltip", True)  
     # second condition in gtk3 
     view.connect('query-tooltip',self.tooltip_callback) 
     # hide tooltip when mouse out of widget 
     view.connect("leave-notify-event", self.__leave_handler) 

    def get_tooltip(self, view, column, path): 
     """in order to secure customized implementation in your projet""" 
     'See the module doc string for a description of this method' 

     raise NotImplemented('Subclass must implement get_tooltip()') 

if __name__ == '__main__': 


    class DemoTips_Gtk3(TreeViewTooltips_gtk3): 
     """demo play how to """ 
     def __init__(self, customer_column): 
      """ 
      init class 
      customer_column is an instance of Gtk.TreeViewColumn and 
      is being used in the Gtk.TreeView to show customer names.""" 
      self.cust_col = customer_column 
      # call base class init 
      TreeViewTooltips_gtk3.__init__(self) 

     def get_tooltip(self, column,cust_col,path): 
      """By checking both column and path we have a cell-based tooltip"""  
      model = view.get_model() 
      customer = model[path][2]  
      if column is cust_col: 
       """here there is lot of information on row""" 
       return '<big>%s %s</big>\n<i>%s</i>' % (customer.fname, 
                 customer.lname, 
                 customer.notes) 
      else: 
       """here basic data only !!!!""" 
       return ('<big><u>Generic Column Tooltip</u></big>\n' 
         'Unless otherwise noted, all\n phone number is %s ') % customer.phone 


    # Here's our customer 
    class Customer: 

     def __init__(self, fname, lname, phone, notes): 
      self.fname = fname 
      self.lname = lname 
      self.phone = phone 
      self.notes = notes 


    # create a bunch of customers 
    customers = [] 
    for fname, lname, phone, notes in [ 
     ('Joe', 'Schmoe', '555-1212', 'Likes to Morris dance.'), 
     ('Jane', 'Doe', '555-2323', 
     'Wonders what the hell\nMorris dancing is.'), 
     ('Phred', 'Phantastic', '900-555-1212', 'Dreams of Betty.'), 
     ('Betty', 'Boop', '555-3434', 'Dreams in b&amp;w.'), 
     ('Red Sox', 'Fan', '555-4545', 
     "Still livin' 2004!\nEspecially after 2006.")]: 
     customers.append(Customer(fname, lname, phone, notes)) 



    # Build our model and view 
    model = Gtk.ListStore(str, str, object) 
    for c in customers: 
     model.append(['%s %s' % (c.fname, c.lname), c.phone, c]) 

    view = Gtk.TreeView(model) 

    # two columns, name and phone 
    cell = Gtk.CellRendererText() 
    cell.set_property('xpad', 20) 
    namecol = Gtk.TreeViewColumn('Customer Name', cell, text=0) 
    namecol.set_min_width(200) 
    view.append_column(namecol) 

    cell = Gtk.CellRendererText() 
    phonecol = Gtk.TreeViewColumn('Phone', cell, text=1) 
    view.append_column(phonecol) 

    # finally, connect the tooltip, specifying the name column as the 
    # column we want the tooltip to popup over. 
    tips = DemoTips_Gtk3(namecol) 
    tips.add_view(view) 

    # We're going to demonstrate enable/disable. First we need a 
    # callback function to connect to the toggled signal. 
    def toggle(button): 
     if button.get_active(): 
      tips.disable() 
     else: 
      tips.enable() 

    # create a checkbutton and connect our handler 
    check = Gtk.CheckButton('Check to disable view tooltips') 
    check.connect('toggled', toggle) 


    check.set_tooltip_markup('This is a standard Gtk tooltip.\n' 
         'Compare me to the tooltips above.') 

    # create a VBox to pack the view and checkbutton 
    vbox = Gtk.VBox() 
    vbox.pack_start(view,False,False,2) 
    vbox.pack_start(check,False,False,2) 
    vbox.show_all() 

    # pack the vbox into a simple dialog and run it 
    dialog = Gtk.Dialog('TreeViewTooltips Demo') 
    tips.dialog = dialog #give tips the main window reference 
    close = dialog.add_button(Gtk.STOCK_CLOSE,Gtk.ResponseType.NONE) 
    # add a tooltip for the close button 
    close.set_tooltip_markup('Click to end the demo.') 

    dialog.set_default_size(400,400) 
    dialog.vbox.pack_start(vbox,False,False,2) 
    dialog.run() 

以下のコード(クリーンアップではなく)修正ご覧ください。

関連する問題