【问题标题】:GTK detecting window resize from the userGTK 检测用户调整窗口大小
【发布时间】:2009-06-29 19:27:13
【问题描述】:

在 GTK(或 pygtk 或 gtkmm...)中

我如何检测到应用程序窗口已被用户手动调整大小,这通常是通过拖动窗口的边缘来完成的?

我需要找到一种方法来区分手动调整大小与源自 gtk 的调整大小,例如窗口内容的更改。

【问题讨论】:

  • 你找到办法了吗?
  • 没有。如果我这样做,它会显示在这里。

标签: gtk signals resize


【解决方案1】:

您是否尝试连接到 GDK_CONFIGURE 事件?

在下方查看this example “移动窗口”部分。该示例显示了在移动窗口时执行某些操作的回调,但配置事件是移动、调整大小和堆栈顺序事件的全部。

【讨论】:

  • 以下代码适用于此:g_signal_connect(G_OBJECT(window), "configure-event", G_CALLBACK(callback_func), NULL);
  • 我认为你可以使用“check-resize”而不是“configure-event”
  • 但这并没有提供一种方法来检查发生了什么类型的事件:调整大小或移动。因此,如果用户无法以某种方式确定这一点,那么肯定会产生虚假的结果。 @boldnik:据此,这是行不通的,因为它会因各种其他原因而触发:ubuntuforums.org/…
  • 给定的链接已失效且编辑队列已满。这是给定示例的当前链接:zetcode.com/gui/gtk2
  • @boldnik check_resize 在我身边不断触发。我认为 configure-event 最有可能是正确的方向。
【解决方案2】:

我设法通过观察GtkWindow 上的size_allocatesize_request 信号来解决这个问题。如果size_request 变小了,我就打电话给resize(1,1)。如果size_allocate 比预期大,我关闭了系统。

我确保要处理的一件事是 size_request 返回先大后小,让 size_allocate 大后小。我不知道这是否可行,但我通过确保仅在获得较小的 size_allocate 而不是在获得较小的 size_request 时减少 size_allocate 的预期值来修复它。

确保您的 size_request 处理程序位于基类的处理程序之后,以便您获得正确的值。我通过重写方法然后首先调用基类方法来做到这一点。

我在 1 维和 2 维中都试过了,它似乎都可以工作。

【讨论】:

    【解决方案3】:

    在我的例子中,我试图区分用户调整 Gtk.Paned 的大小和用户调整整个窗口的大小。两者都发出了notify::position 信号。

    我的解决方案是,因为我不知道用户是否正在从小部件调整窗口大小,所以反转我想知道的内容。记录用户是否重新定位了小部件,如果用户没有在我的小部件上启动更新,则忽略更新。

    也就是说,我没有测试“如果窗口被调整大小”,而是在本地记录了button-press-eventbutton-release-event,因此我可以测试“如果小部件被重新定位”

    from gi.repository import Gtk
    
    class MyPaned(Gtk.Paned):
        _user_activated = False
    
        def on_position(self, _, gparamspec):
            if self._user_activated:
                # widget touched
    
            else:
                # window resized (probably)
    
        def on_button_press(self, *_):
            self._user_activated = True
    
        def on_button_release(self, *_):
            self._user_activated = False
    
    
        dev __init__(self, *args):
            super(MyPaned, self).__init__(*args)
            self.connect('notify::position', self.on_position)
            self.connect('button-press-event', self.on_button_press)
            self.connect('button-release-event', self.on_button_release)
    
    

    有效地通过记录用户开始和结束与我的小部件直接交互的时间,我可以假设其余时间是由于调整了窗口大小。 (直到我找到更多案例)

    【讨论】:

    • 在 API 参考中的哪里可以找到notify::position
    • @buhtz 我想我在野外偶然发现了一个“notify::”示例,我推断其余部分来自 Lazka 的出色 PGI 文档:lazka.github.io/pgi-docs/#Gtk-3.0/classes/Paned.html
    • @ThorSummoner 在文档中我找不到notify::* 事件。这就是我想知道的原因。
    • @ThorSummoner 是的,我想在您的代码 sn-p 中添加 python3 语法突出显示,但 SE 告诉我您的答案的 编辑队列 已满。
    • 如果有用户使用平铺窗口管理器,这段代码将无法正常工作
    【解决方案4】:

    在 PyGTK 中,我一直关注 expose_event 来调整窗口大小,然后使用 get_allocation 方法来获取新大小。

    【讨论】:

    • 我正在查看 GdkEventExpose 结构...是 send_event 字段告诉我用户做了吗?
    • 实际上,您可能想要 event_configure,而不是 event_expose……我的错。我认为移动和调整大小都需要这样做,因此如果您只对之前的大小感兴趣,则必须记住之前的大小。
    【解决方案5】:

    您可以通过使用gdk_window_get_root_origin 获取窗口的左上角和gdk_window_get_geometry 获取宽度和高度来将一些东西放在一起。然后,您可以将回调挂钩到 GDK_BUTTON_PRESS_MASK 并检查按钮按下是否发生在窗口边缘之一附近/上。

    当然,这看起来很老套,我在 GdkWindow 的文档中找不到一些简单的方法来执行此操作,这让我很困扰。有一个gdk_window_begin_resize_drag 函数真的让我觉得有一种更清洁的方法可以做到这一点,但我没有看到比我的答案更明显的东西。

    【讨论】:

      猜你喜欢
      • 2019-02-21
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      相关资源
      最近更新 更多