对话在Vala绊倒

时间:2013-12-24 22:50:14

标签: vala

我最近一直在尝试使用Vala编程。我在其他语言编程方面有相当丰富的经验,但近年来主要使用Python,Tcl和Perl等脚本语言。 Elementary OS干净的外观给我留下了深刻的印象,这让我开始关注Vala,我必须说我的第一印象非常积极。但是,我遇到了Dialog编程的问题,我认为更有经验的Vala程序员可能会提供帮助。在我最新的测试程序中,我使用基于Dialog的例程来获取值(getYesNo),然后使用另一个基于Dialog的例程(showDialog)显示一个描述该值的字符串。两个例程在独立使用时都能正常工作,但是如上所述一起使用时,显示事件将被保留,直到对值获取例程进行第二次调用。这听起来像是对“flush_events”的调用在Perl或Tcl中解决的那种情况。但是我如何在Vala中处理它呢?或者有没有办法避免它首先发生?

代码:

using Gtk;
using Posix;

public class DialogTestWindow: ApplicationWindow {

    private int RESPONSE;
    private Toolbar tbMain = new Toolbar();
    private ToolButton bAbout = new ToolButton(new Image.from_icon_name
        ("help-about",IconSize.SMALL_TOOLBAR),null);
    private ToolButton bDoIt = new ToolButton(new Image.from_icon_name
        ("media-record",IconSize.SMALL_TOOLBAR),null);
    private ToolButton bQuit = new ToolButton(new Image.from_icon_name
        ("application-exit",IconSize.SMALL_TOOLBAR),null);

    internal DialogTestWindow(DialogTest app) {
        Object(application: app, title: "DialogTest");
        this.window_position = WindowPosition.CENTER;
        this.set_default_size(720,480);
// ---- Set up Toolbar ----------------------------------------------------
        tbMain.get_style_context().add_class(STYLE_CLASS_PRIMARY_TOOLBAR);
        bQuit.is_important = true;
        bQuit.clicked.connect(onQuit);
        tbMain.add(bQuit);
        bAbout.is_important = true;
        bAbout.clicked.connect(onAbout);
        tbMain.add(bAbout);
        bDoIt.is_important = true;
        bDoIt.clicked.connect(onDoIt);
        tbMain.add(bDoIt);
// ---- Pack Toolbar etc into vBox on main window -------------------------
        Box vbMain = new Box(Orientation.VERTICAL,0);
        vbMain.pack_start(tbMain,false,true,0);
        this.add(vbMain);
        this.show_all();
        printf("Started\n");
    }
// ==== getYesNo ==========================================================
    private void getYesNo(string message) {
        Dialog dialog = new Dialog.with_buttons
            ("Get",this,DialogFlags.MODAL,
            Stock.YES,ResponseType.YES,Stock.NO,ResponseType.NO,null);
        var content = dialog.get_content_area();
// warning: assignment from incompatible pointer type
// [enabled by default]
        Label label = new Label(message);
        label.set_line_wrap(true);
        content.add(label);
        dialog.response.connect((id)=>{
            printf("response id=%i\n",id);
            RESPONSE = id;
            dialog.destroy();
        });
        dialog.show_all();
    }
// ==== onAbout ===========================================================
    private void onAbout() {
        Dialog dialog = new Dialog.with_buttons
            ("About",this,DialogFlags.MODAL,
            Stock.OK,ResponseType.OK,null);
        var content = dialog.get_content_area();
// warning: assignment from incompatible pointer type
// [enabled by default]
        Label label = new Label("This program tests pop-up dialogs");
        content.add(label);
        dialog.response.connect(()=>{dialog.destroy();});
        dialog.show_all();
    }
// ==== onDoIt ============================================================
    private void onDoIt() {
        getYesNo("Well?");
        if (RESPONSE==ResponseType.YES) showDialog("YES!");
    }
// ==== onQuit ============================================================
    private void onQuit() {
        printf("Ending\n");
        exit(-1);
    }
// ==== showDialog ========================================================
    private void showDialog(string message) {
        Dialog dialog = new Dialog.with_buttons
            ("Show",this,DialogFlags.MODAL,
            Stock.OK,ResponseType.OK,null);
        var content = dialog.get_content_area();
// warning: assignment from incompatible pointer type
// [enabled by default]
        Label label = new Label(message);
        label.set_line_wrap(true);
        content.add(label);
        dialog.response.connect((id)=>{dialog.destroy();});
        dialog.show_all();
    }

}

public class DialogTest: Gtk.Application {
    internal DialogTest() {
        Object(application_id: "org.test.DialogTest");
    }
    protected override void activate() {
        new DialogTestWindow(this).show();
    }
}

extern void exit(int exit_code);

public int main(string[] args) {
    return new DialogTest().run(args);
}

1 个答案:

答案 0 :(得分:1)

使用Gtk.Dialog.run,而不是Gtk.Widget.show_all。这将阻止主循环,直到对话框返回结果,而不是同时显示两个对话框。