2017-06-21 87 views
0

我有一個基於GtkHeaderBar的基於自定義GtkDrawingArea的小部件,它基本上是一個接收鼠標點擊和移動的滑塊。在GTK 3.14中一切正常,但在3.22的東西南下:當我點擊並拖動我的小部件時,GTK認爲我試圖拖動窗口(前幾個像素轉到窗口小部件,但窗口接管)。GTK3:小工具鼠標事件傳遞

如何防止鼠標事件傳播到窗口?

motion-notify-event和button-press-event都返回TRUE(它已經在3.14中做了訣竅,不再)。

g_sinal_connect(Something->DrawingArea, "motion-notify-event", G_CALLBACK(Something_motion), Something); 
g_signal_connect(Something->DrawingArea, "button-press-event", G_CALLBACK(Something_press), Something); 
+0

是否有安裝在其上捕獲的事件您的繪圖元素的任何處理(S)?請記住,您必須使用FALSE結束這些處理程序,才能將事件發送到基礎小部件。你如何繪製自定義小部件? – jcoppens

+0

@jcoppens,我有3個處理程序:motion-notify-event,button-press-event和button-release-event。我想阻止它們傳播到底層窗口小部件(準確地說是GtkHeaderBar),這就是爲什麼我返回TRUE。它曾經工作,但停止在較新的GTK版本中工作。我在「draw」回調中使用開羅繪製。 – NK22

回答

0

回答爲答案,因爲我無法在代碼中輸入'comments'。

我懷疑你必須啓用對應於DrawingAreaEventMask。我想,這與其他小部件有些不同。

下面是Python3一個demo程序(這基本上是直接連接到Gtk3.2x庫,所以應該是類似於你想在C.

做改變area_button_press()返回TrueFalse會出現什麼。使它透明到button_press_event,如預期評論與...add_events(Gdk.EventMask.BUTTON_PRESS_MASK)線需要在所述代碼,以使button-press-event要在所有確認:

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
# 
# test_headerbar_events.py 
# 
# Copyright 2017 John Coppens <[email protected]> 
# 
# 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. 
# 
# 


from gi.repository import Gtk, Gdk 

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

     hdrbar = Gtk.HeaderBar(title = "Header bar") 
     hdrbar.connect("button-press-event", self.hdrbar_button_press) 

     drawing_area = Gtk.DrawingArea() 
     drawing_area.set_size_request(30, 30) 
     drawing_area.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) 
     drawing_area.connect("button-press-event", self.area_button_press) 

     frame = Gtk.Frame() 
     frame.add(drawing_area) 

     hdrbar.pack_start(frame) 

     self.add(hdrbar) 
     self.show_all() 

    def area_button_press(self, btn, event): 
     print("Button pressed on Drawing Area") 
     return True 

    def hdrbar_button_press(self, btn, event): 
     print("Button pressed on Header Bar") 
     return False 


    def run(self): 
     Gtk.main() 


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

    return 0 

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

編輯:如果您使用set_titlebar(),事件似乎直接進入窗口管理器(這可能正是您想要的),而不是基礎窗口。如果你想控制(塊)窗口的運動,你可以

  • 不使用set_titlebar()和使用set_decorations(False),這將隱藏窗口的標題欄,並在頂部顯示您headerbar。然後事件將是可控的。使用VBox來存儲標題欄和窗口其餘部分的內容。

  • 當然。這樣你將不得不實現窗口拖動自己(這不是太複雜)。如果需要的話,看看在GUI frontend I made for the Wcalc calculator(年前 - 你可能需要調整GTK的調用),

+0

我注意到刪除GDK_POINTER_MOTION_MASK確實會阻止窗口拖動。當然,這也會使繪畫區域沒有任何事件發生。你的python示例與我的情況有些不同:用self.set_titlebar(hdrbar)替換self.add(hdrbar),然後添加POINTER_MOTION_MASK來證明問題。 – NK22

+0

我明白了......我已經爲上面的答案添加了一個編輯。也許這是解決您的問題? – jcoppens

+0

我剛來這裏說我決定徹底扔掉GTK3。還有其他的問題,在我看來,這個平臺是不可信的。我寧願不讓我的項目依靠它。不管怎麼說,還是要謝謝你。 – NK22