【问题标题】:Save/restore window position in GTK在 GTK 中保存/恢复窗口位置
【发布时间】:2011-04-28 16:10:04
【问题描述】:

我想在程序启动之间保存/恢复窗口位置。 窗口可以最大化。这也应该保存。 问题是在最大化(缩放)时保存窗口位置。

所以细节(我不关心保存,这是很简单的任务)。 我需要获取窗口正常状态的 x,y,width,height 并标记窗口是否最大化的方法。 不幸的是 gdk_window_get_size/gdk_window_get_position 返回实际的窗口位置。

在 Windows 下使用 GetWindowPlacement 和 rcNormalPosition 可以轻松解决此问题。 但我需要一个 Mac OS X Cocoa(至少)或纯 GTK 中的解决方案。

【问题讨论】:

    标签: c++ cocoa gtk quartz-graphics


    【解决方案1】:

    为此,我所做的是使用在您调整 Gtk.Window 大小时发出的信号,通过 gsettings 我保存值并恢复它以以相同的方式启动应用程序。这是 vala + GTK+ 中的一个例子:

    using Gtk;
    using GLib;
    
    public class Prueba : Window {
    
        public void on_resize (Window win)
        {
            int width;
            int height;
    
            win.get_size (out width, out height);
    
            /* GSETTINGS CONFIG */
            string settings_dir = Path.get_dirname (".");
    
            SettingsSchemaSource sss = new SettingsSchemaSource.from_directory (settings_dir, null, false);
            SettingsSchema schema = sss.lookup ("apps.test-gs", false);     
    
            if (sss.lookup == null)
            {
                stdout.printf ("GLIB.GIO.SCHEMA: ID not found.");
            }
    
            GLib.Settings config = new GLib.Settings.full (schema, null, null);
            /* GSETTINGS FIN */
    
            stdout.printf ("RESOLUTION: %dx%d\n", width, height);
    
            config.set_int ("width", width);
            config.set_int ("height", height);
        }
    
        public void on_destroy (Window ventana)
        {
    
            stderr.printf ("APPLICATION EXIT!\n");
            Gtk.main_quit ();
        }
    
        public Prueba ()
        {
            this.title = "Prueba GTK+";
    
            string settings_dir = Path.get_dirname (".");
            SettingsSchemaSource sss = new SettingsSchemaSource.from_directory (settings_dir, null, false);
            SettingsSchema schema = sss.lookup ("apps.test-gs", false);
    
            if (sss.lookup == null)
            {
                stdout.printf ("GLIB.GIO.SCHEMA: ID not found.");
            }
    
            GLib.Settings settings = new GLib.Settings.full (schema, null, null);
    
            this.set_default_size (settings.get_int("width"), settings.get_int("height"));
            this.border_width = 10;
            this.window_position = WindowPosition.CENTER;
    
            Button b = new Button.with_label ("SALIR");
    
            b.clicked.connect (()=>{
                    this.on_destroy (this);
                });
    
            this.add (b);
            this.show_all ();
        }
    
        public static int main (string[] args)
        {
            Gtk.init (ref args);
    
            Prueba app = new Prueba ();
    
            app.destroy.connect (()=> {
    
                app.on_destroy (app);
    
            });
    
            app.size_allocate.connect (()=>{
                    app.on_resize (app);
            });
    
            Gtk.main ();
            return 0;
        }
    
    }
    

    以及用于此的架构:

    <?xml version="1.0" encoding="UTF-8"?>
    <schemalist>
        <schema id="apps.test-gs" path="/apps/test-gs/">
            <key type="b" name="check-test">
                <default>false</default>
                <summary>Check de mi app TEST</summary>
                <description>Es un ejemplo de BOOLEANO de mi APP TEST</description>
            </key>
            <key type="i" name="width">
                <default>300</default>
                <summary>Pixels del Ancho</summary>
                <description>Valor del Ancho del Programa TEST</description>
            </key>
            <key type="i" name="height">
                <default>100</default>
                <summary>Pixels del Alto</summary>
                <description>Valor del Alto del Programa TEST</description>
            </key>
        </schema>
    </schemalist>
    

    祝你好运!

    【讨论】:

    • 对于 GTK3,重要的是不要连接破坏信号:developer.gnome.org/SaveWindowStateIt is important to note that you should not use the GtkWidget::destroy signal to retrieve the state of a GtkWindow in order to store it somewhere. The GtkWidget::destroy signal is meant to be used to release external references, which means that the widget is not guaranteed to be in the same state as to when the window's close button was pressed, or the "Quit" action was called.
    【解决方案2】:

    Window Programming Guide 中的Saving Window Position 中描述了 Cocoa* 解决方案。让您的应用程序委托执行:

    [window setFrameAutosaveName:@"MyWindowFrame"];
    

    使窗口在框架发生变化时自动将其框架保存到用户默认值中。然后在下一次发布时,

    [window setFrameUsingName:@"MyWindowFrame"];
    

    窗口知道is "zoomed"(最大化):

    [window isZoomed];
    

    这样您就可以随时获得此标志以及框架:

    // Gives you an NSRect in screen coordinates
    [window frame];
    

    根据文档,isZoomedzoom 通过 windowWillUseStandardFrame:defaultFrame: 与窗口的委托进行检查。我不确定您想在这里深入 Cocoa,但这看起来像是您在评论中提到的情况的一种选择。如果窗口是使用缩放框架创建的,我认为窗口委托对象可以通过此方法为框架提供合理的默认值。


    *和Obj-C,因为我不懂C++。

    【讨论】:

    • 不幸的是,当最大化窗口关闭时它不起作用。在这种情况下,它将被加载为最大化,但“加号”按钮什么也不做。 IE。正常状态和最大化状态具有相同的位置。
    • @user729666:我明白了。添加了一些建议。
    【解决方案3】:

    我刚刚使用pygobject 实现了这样的事情;它不是 C++,但它仍然有用。

    您可以找到代码here

    我已将 GNOME Builder 的默认模板用于 Python GNOME 应用程序,因此如果您使用它设置项目,它应该非常容易复制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-27
      • 2012-03-29
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2022-01-26
      • 2011-02-20
      • 1970-01-01
      相关资源
      最近更新 更多