避免关闭GTK对话框

时间:2018-03-29 08:10:18

标签: dialog modal-dialog gtk gtk3

在按下OK按钮之后但是在GTK对话框中关闭对话框之前,有没有办法运行代码?我希望能够在按下OK按钮后语法检查输入到对话框中的一些代码,并且如果代码无法编译,则可以选择保持对话框打开。经过一段谷歌搜索后,我找到了How to avoid closing of Gtk.Dialog in Python?,但遗憾的是答案很缺乏细节,所以我无法弄清楚如何实现这一点。如何做到这一点?

编辑:虽然链接的问题具体涉及Python,但我实际上并不关心任何特定的语言。我正在使用Haskell绑定,但我对使用GTK +绑定的任何语言的答案都很好。

编辑:如果您发现此问题试图找出如何进行验证,但没有我的复杂要求,我强烈建议您查看下面的@AlexanderDmitriev's answer。< / p>

3 个答案:

答案 0 :(得分:1)

看起来GtkDialog本身并不允许取消按下按钮(从用户的角度来看这是可以的)。但是,每次用户更改某些内容时,您都可以检查它并使按钮变得敏感。我已经延长了code from answer to mentioned question

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

class DialogExample(Gtk.Dialog):

    #this variable controls, whether OK is sensitive
    button_state = True 

    def switch_state(button, de):
        print ("switcher")
        de.button_state = not de.button_state
        de.set_response_sensitive (Gtk.ResponseType.OK, de.button_state)


    def __init__(self, parent):
        Gtk.Dialog.__init__(self, "My Dialog", parent, 0,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
             Gtk.STOCK_OK, Gtk.ResponseType.OK))

        self.set_default_size(150, 100)

        label = Gtk.Label("This is a dialog to display additional information")

        box = self.get_content_area()
        # a button to switch OK's sensitivity
        state_switcher_btn = Gtk.Button ("Switch")
        state_switcher_btn.connect ("clicked", DialogExample.switch_state, self)

        box.add(label)
        box.add(state_switcher_btn)

        self.show_all()

    def do_response (self, response_id):
        print ("Override! ID is ", response_id)

class DialogWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Dialog Example")

        self.set_border_width(6)

        button = Gtk.Button("Open dialog")
        button.connect("clicked", self.on_button_clicked)

        self.add(button)

    def on_button_clicked(self, widget):
        dialog = DialogExample(self)
        response = dialog.run()

        if response == Gtk.ResponseType.OK:
            print("The OK button was clicked")
        elif response == Gtk.ResponseType.CANCEL:
            print("The Cancel button was clicked")

        dialog.destroy()

win = DialogWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

答案 1 :(得分:0)

我曾经也有这个。我决定抓住response信号。我有一个可以处理验证的函数。但是,处理response信号的函数始终返回True以向GTK显示信号已被处理且对话框未关闭。如果对话框需要关闭,我手动完成。

myDialogWindow.connect("response", validate_response)

def validate_response(dialog, response_id):
     # validate
     if correct:
        dialog.destroy()
     else:
        print("Something went wrong")
     return True

虽然这可以完成工作,但我不确定这是最GTK的解决方案。

答案 2 :(得分:0)

我添加了另一个答案,以使之前的答案有效。

我看到了两种实现理想行为的方法。

  1. 使用已弃用的gtk_dialog_get_action_area并在那里打包按钮
  2. 停止信号发射以防止GtkDialog&#34;看到&#34;按下了响应按钮。
  3. 这两种方式都可以在下面的代码中找到。查找第一个方法的deprecated和第二个的awesome

        import gi
        gi.require_version('Gtk', '3.0')
        from gi.repository import Gtk
    
        class DialogExample(Gtk.Dialog):
    
            button_state = True
    
            def awesome_cb (button, de):
                if de.button_state:
                    print("Awesome ok")
    
                else:
                    print("Awesome  Not allowed")
                    button.stop_emission_by_name ("clicked")
    
            def deprecated_cb (button, de):
                if de.button_state:
                    print("Deprecated ok")
                    de.response(11)
                else:
                    print("Deprecated Not allowed");
    
            def switch_state(button, de):
                de.button_state = not de.button_state
                de.dialog_ok_btn.set_sensitive (de.button_state)
    
    
            def __init__(self, parent):
                Gtk.Dialog.__init__(self, "My Dialog", parent, 0,
                    (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                     Gtk.STOCK_OK, Gtk.ResponseType.OK))
    
                self.set_default_size(150, 100)
    
                label = Gtk.Label("This is a dialog to display additional information")
    
                box = self.get_content_area()
                state_switcher_btn = Gtk.Button ("Switch")
                state_switcher_btn.connect ("clicked", DialogExample.switch_state, self)
    
                box.add(label)
                box.add(state_switcher_btn)
    
                hard_work_button = Gtk.Button ("deprec")
                hard_work_button.connect ("clicked", DialogExample.deprecated_cb, self)
    
                carea = self.get_action_area()
                carea.add (hard_work_button)
    
                tfb = Gtk.Button ("awesome");
                tfb.connect("clicked", DialogExample.awesome_cb, self)
                self.add_action_widget(tfb, 12)
    
                self.dialog_ok_btn = self.get_widget_for_response (Gtk.ResponseType.OK)
                self.show_all()
    
            def do_response (self, response_id):
                print ("Response! ID is ", response_id)
    
        class DialogWindow(Gtk.Window):
    
            def __init__(self):
                Gtk.Window.__init__(self, title="Dialog Example")
    
                self.set_border_width(6)
    
                button = Gtk.Button("Open dialog")
                button.connect("clicked", self.on_button_clicked)
    
                self.add(button)
    
            def on_button_clicked(self, widget):
                dialog = DialogExample(self)
                response = dialog.run()
    
                if response == Gtk.ResponseType.OK:
                    print("The OK button was clicked")
                elif response == Gtk.ResponseType.CANCEL:
                    print("The Cancel button was clicked")
    
                dialog.destroy()
    
        win = DialogWindow()
        win.connect("delete-event", Gtk.main_quit)
        win.show_all()
        Gtk.main()