我最近一直在尝试使用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);
}
答案 0 :(得分:1)
使用Gtk.Dialog.run,而不是Gtk.Widget.show_all。这将阻止主循环,直到对话框返回结果,而不是同时显示两个对话框。