【问题标题】:Gtk4 GestureClick no released signal emittedGtk4 GestureClick 没有释放信号
【发布时间】:2022-07-12 00:25:25
【问题描述】:

当我将 Gtk.GestureClick 分配给 Gtk.Scale 时,不会发出 released 信号。

参见代码示例。

import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk

class Main():
    def on_activate(self, app):
        win = Gtk.ApplicationWindow(application=app)
        gesture = Gtk.GestureClick.new()
        gesture.connect("pressed", self.press)
        gesture.connect("released", self.release)
        scale = Gtk.Scale()
        win.set_child(scale)
        scale.add_controller(gesture)
        win.present()

    def press(self, *_):
        print("pressed")

    def release(self, *_):
        print("released")

app = Gtk.Application(application_id='com.example.GtkApplication')
runner = Main()
app.connect('activate', runner.on_activate)

app.run(None)

【问题讨论】:

    标签: python-3.x linux user-interface gtk gtk4


    【解决方案1】:

    我实际上查看了 GTK“GestureClick”小部件的源代码,我在代码中发现“已释放”信号仅在单击事件结束时发出 (gtk_gesture_click_end)。该事件与 GTK Gesture 小部件的“结束”信号相关联。因此,作为一个测试,我修改了“self.release”函数以利用小部件继承的“end”事件,如下所示。

    gesture.connect("end", self.release)
    

    然后在打印“按下”后立即在终端上打印出“释放”一词,但它是作为点击事件的一部分进行的,并且不会等待鼠标按钮的实际释放。

    您可以尝试我的小代码更改来看看效果。我很犹豫是否将其称为错误,因为此时我对 GTK 手势还没有太多经验。但是,测试一下。此时您可能只需要依赖点击事件。

    其他发现。

    简而言之,在查看其他 GTK4 单击手势示例时,“按下”和“释放”手势都可以与其他小部件一起使用。显然,比例小部件有一些特殊性。我修改了您在标签小部件中为比例小部件交换的示例代码。

    import gi
    gi.require_version('Gtk', '4.0')
    from gi.repository import Gtk
    
    class Main():
        def on_activate(self, app):
            win = Gtk.ApplicationWindow(application=app)
            gesture = Gtk.GestureClick.new()
            gesture.connect("pressed", self.press)
            gesture.connect("released", self.release)
            label = Gtk.Label(label="This is a label widget")
            win.set_child(label)
            win.set_default_size(400, 200)
            label.add_controller(gesture)
            win.present()
            
        def press(self, *_):
            print("pressed")
        
        def release(self, *_):
            print("released")
        
    app = Gtk.Application(application_id='com.example.GtkApplication')
    runner = Main()
    app.connect('activate', runner.on_activate)
    
    app.run(None)
    

    以下是在标签小部件上单击并释放鼠标按钮的终端输出结果。

    仅供参考,为了确认这个问题似乎与比例小部件有关,我用 C 语言构建了一个类似的程序,测试比例小部件与其他小部件的对比。同样,比例小部件不会发出释放信号。至少比例小部件的特性在不同的语言中是一致的。所以看起来底线是缩放小部件不会发出释放信号。我希望额外的信息有所帮助。

    问候。

    【讨论】:

    • 感谢您的回答!你是对的,似乎Gtk.Scale 占据了焦点或其他东西,它立即发出end 信号。奇怪的。它可能是也可能不是错误,但无论如何,到目前为止,我似乎必须寻找解决方法。
    • 仅供参考,我做了更多调查。请参阅我附加到我的答案的“附加说明”。 GTK 缩放小部件似乎有一些问题,无法发出释放的信号。
    • 感谢您的研究!很高兴知道它与语言无关,并且似乎仅限于比例小部件。与此同时,我研究了其他可能的解决方案(检测何时抓取和释放秤),但到目前为止还没有运气。希望这将在上游解决,如果它确实是一个错误。
    【解决方案2】:

    我有同样的问题,但我暂时用 gtk 按钮修复了。使用取消信号释放。它对我有用。

    func (c *Control) topCenter() *gtk.Box {
        boxroot := gtk.NewBox(gtk.OrientationHorizontal, 0)
        boxroot.SetHExpand(true)
    
        root := gtk.NewOverlay()
        root.SetCSSClasses([]string{"player-control-scale"})
        root.SetHExpand(true)
    
        c.cacheadjustment = gtk.NewAdjustment(0, 0, 1, 1, 10, 0)
        c.cacheprocess = gtk.NewScale(gtk.OrientationHorizontal, c.cacheadjustment)
        c.cacheprocess.AddCSSClass("timescalebuffer")
        root.SetChild(c.cacheprocess)
    
        c.timeadjustment = gtk.NewAdjustment(0, 0, 1, 1, 10, 0)
        c.timeprocess = gtk.NewScale(gtk.OrientationHorizontal, c.timeadjustment)
        c.timeprocess.AddCSSClass("timescale")
    
        tsstext := gtk.NewLabel("testing")
        timepopover := gtk.NewPopover()
        timepopover.SetSizeRequest(80, 0)
        timepopover.SetChild(tsstext)
        timepopover.SetPosition(gtk.PosTop)
        timepopover.SetAutohide(false)
        boxroot.Append(timepopover)
        timepopover.AddCSSClass("timePopup")
    
        motionctrl := gtk.NewEventControllerMotion()
        c.timeprocess.AddController(motionctrl)
    
        motionctrl.ConnectEnter(func(x, y float64) {
            glib.IdleAddPriority(glib.PRIORITY_HIGH_IDLE, func() {
                rect := gdk.NewRectangle(int(x), 0, 0, 0)
                timepopover.SetPointingTo(&rect)
                timepopover.Show()
            })
        })
    
        motionctrl.ConnectLeave(func() {
            glib.IdleAddPriority(glib.PRIORITY_HIGH_IDLE, func() {
                timepopover.Hide()
            })
        })
    
        motionctrl.ConnectMotion(func(x, y float64) {
            glib.IdleAddPriority(glib.PRIORITY_HIGH_IDLE, func() {
    
                rect := gdk.NewRectangle(int(x), 0, 0, 0)
                timepopover.SetPointingTo(&rect)
                prr := math.Round(percent.PercentOf(int(x), c.timeprocess.AllocatedWidth()))
                step := c.timeadjustment.StepIncrement()
                value := (step*math.Round(prr*(c.duration-0)/step) + 0) / 100
                drtime, _ := time.ParseDuration(fmt.Sprintf("%fs", value))
                c.Lock()
                c.lastValPos = drtime
                c.Unlock()
    
                currentTime := parsing.NewTime().Duration(drtime)
                tsstext.SetText(currentTime)
                if drtime.Seconds() < 0 {
                    timepopover.Hide()
                } else if drtime.Seconds() > c.duration {
                    timepopover.Hide()
                } else {
                    if !timepopover.IsVisible() {
                        timepopover.Show()
                    }
                }
    
            })
        })
    
        root.AddOverlay(c.timeprocess)
    
        // add button for temp fixed when gtk scale not emitted release signal
        c.btntracks = gtk.NewButton()
        c.btntracks.SetCSSClasses([]string{"transparent-btn"})
    
        clickges := gtk.NewGestureClick()
        c.timeprocess.AddController(clickges)
    
        clickges.ConnectPressed(func(nPress int, x, y float64) {
            fmt.Println("ConnectPressed")
            c.Lock()
            c.seekOnHold = true
            c.Unlock()
        })
    
        // use cancel for release signal
        clickges.ConnectCancel(func(sequence *gdk.EventSequence) {
            fmt.Println("ConnectCancel")
            c.Lock()
            c.seekOnHold = false
            c.Unlock()
    
            glib.IdleAddPriority(glib.PRIORITY_HIGH_IDLE, func() {
                c.Lock()
                val := c.lastValPos.Seconds()
                c.Unlock()
                c.timeadjustment.SetValue(val)
                c.main.player.Bridge().Seek(val)
            })
        })
    
        c.btntracks.SetChild(root)
        c.timeprocess.SetSensitive(false)
        c.cacheprocess.SetSensitive(false)
        c.btntracks.SetSensitive(false)
        boxroot.Append(c.btntracks)
    
        return boxroot
    }
    

    并为透明按钮添加css

    .transparent-btn{
        background:transparent;
        box-shadow: none;
        border-radius: 0px;
        border: 0px;
        text-shadow: none; 
        -gtk-icon-shadow: none;
        padding: 0px;
        &:hover{
            box-shadow: none;
            background: transparent;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-14
      • 1970-01-01
      • 2022-11-03
      • 2021-12-28
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      相关资源
      最近更新 更多