在pyg中处理双击和单击事件

2024-10-02 20:30:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图使用glib.timeout_add()glib.source_remove()将单键单击事件与双击事件分开。我是这样做的:

class Exchange:

'''

some code

'''

    def __init__(self):

        self.timeoutID_1 = 0
        self.timeoutID_2 = 0

        self.startTime1 = 0.0
        self.stopTime1 = 0.0
        self.startTime2 = 0.0
        self.stopTime2 = 0.0

        '''

        some code

        '''

        ## THE DOUBLE CLICK SIGNAL - item-activated
        iconView1.connect("item-activated", self.on_item_activated_1,upButton1, store1)
        sw1.add(iconView1)

        iconView2.connect("item-activated", self.on_item_activated_2,upButton2, store2)
        sw2.add(iconView2)

        ## THE SINGLE CLICK SIGNAL - selection-changed

        iconView1.connect("selection-changed", self.on_selection_changed_1, copyButton1, cutButton1, pasteButton1, deleteButton1)
       iconView2.connect("selection-changed", self.on_selection_changed_2, copyButton2, cutButton2, pasteButton2, deleteButton2)

    def on_selection_changed_1(self, iconView1, copyButton1, cutButton1, pasteButton1, deleteButton1) :


        self.startTime1 = time.time()

        self.timeoutID_1 = glib.timeout_add(2000, self.selectIcon_1, iconView1, copyButton1, cutButton1, pasteButton1, deleteButton1)


    def on_selection_changed_2(self, iconView2, copyButton2, cutButton2, pasteButton2, deleteButton2) :

        self.startTime2 = time.time()

        self.timeoutID_2 = glib.timeout_add(2000, self.selectIcon_2, iconView2, copyButton2, cutButton2, pasteButton2, deleteButton2)


    def selectIcon_1(self, iconView1, copyButton1, cutButton1, pasteButton1, deleteButton1) :

        copyButton1.set_sensitive(True)
        cutButton1.set_sensitive(True)
        pasteButton1.set_sensitive(True)
        deleteButton1.set_sensitive(True)


    def selectIcon_2(self, iconView2, copyButton2, cutButton2, pasteButton2, deleteButton2) :


        copyButton2.set_sensitive(True)
        cutButton2.set_sensitive(True)
        pasteButton2.set_sensitive(True)
        deleteButton2.set_sensitive(True)

    def on_item_activated_1(self, iconView1, item, upButton1, store1) :

        self.stopTime1 = time.time()

        if self.stopTime1 - self.startTime1 < 1.50 :
            glib.source_remove(self.timeoutID_1)

        '''

        some code

        '''

    def on_item_activated_2(self, iconView2, item, upButton2, store2) :

        self.stopTime2 = time.time()

        if self.stopTime2 - self.startTime2 < 1.50 :
            glib.source_remove(self.timeoutID_2)

        '''

        some code

        '''

尽管self.stopTime - self.startTime <1.50True(表示有效的双击),但每次单击仅在2秒后执行一次单击事件。如何完全取消对有效双击的selectIcon方法的执行?在

更新

在mtwebster的回答之后,我尝试使用button_press_event。可惜我又回到原点了。在

^{pr2}$

输出:

vineet@vineet:~/Documents/Project$ python draft6.py
 single click 
 single click 
 double click 

更让我苦恼的是,三次点击事件被执行为一次双击,两次单击和一次双击!!有没有其他的计时机制可以代替glib.timeout_add()来处理重复呼叫的不确定性?在


Tags: selfaddtruetimeondefitemset
3条回答

我不认为移除处理程序是一个好的策略。在

我做过一次这样的破解,将不同的逻辑附加到树视图中的一行上(即单击选择)和双击(即单击执行)。此外,您可能希望支持键盘导航和图像。在

我设法让它在我当时工作的pygtk版本中运行。不过,后来发布了一些小的gtk,我的代码就崩溃了。结果是不可能用相同的代码支持多个版本的gtk。在

最实际的方法是跟踪2个项目:

  • 点击是否指向一个已经选定的对象(在我的案例行中)
  • 这一行是多久前被选中的
    • 默认情况下选择了行(显示/切换视图时的第一行)忽略
    • 行被键盘忽略选定
    • 行选择时间太长(例如300毫秒)忽略
    • 否则(点击选择,小于300ms)执行

您可以计划在双击持续时间之后发生单击事件,然后如果发生双击,请在运行处理程序之前删除计划的单击事件。例如:

import pygtk
pygtk.require('2.0')
import gtk
import glib
class Test:
    def __init__(self):
        # Create a new window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_title("Test")

        # It's a good idea to do this for all windows.
        self.window.connect("destroy", lambda wid: gtk.main_quit())
        self.window.connect("delete_event", lambda a1,a2:gtk.main_quit())

        # Sets the border width of the window.
        self.window.set_border_width(20)

        # Create a new button
        button = gtk.Button("Click")
        self.click_events = []

        # Connect the "clicked" signal of the button to our callback
        button.connect("button-press-event", self.on_button_press_event)
        button.show()

        self.window.add(button)
        self.window.show()

    def on_button_press_event(self, widget, event):
        if event.button == 1:
            if event.type == gtk.gdk._2BUTTON_PRESS:
                # Remove all single click events
                while self.click_events:
                    glib.source_remove(self.click_events.pop()) 
                glib.idle_add(self.handle_double_click,widget,event)
            elif event.type == gtk.gdk.BUTTON_PRESS:
                # Schedule after double click can occur
                self.click_events.append(glib.timeout_add(300,self.handle_single_click,widget,event))


    def handle_single_click(self,widget,event):
        # TODO: Handle single click
        print "TODO: Handle single click"


    def handle_double_click(self,widget,event):
        # TODO: Handle double click
        print "TODO: Handle double click"

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

if __name__ == "__main__":
    main()

我想不是一个有效的答案。。。但你有没有考虑过只连接到IconView的“按下按钮”信号?在

在事件回调中,您可以通过选中event->;type(请参见https://developer.gnome.org/gdk3/stable/gdk3-Event-Structures.html#GdkEventButton)让Gdk决定它是双击事件还是单击事件。在

相关问题 更多 >