View previous topic :: View next topic |
Author |
Message |
zane.sims
Joined: 07 Aug 2007 Posts: 40
|
Posted: Wed Jan 20, 2010 5:55 pm Post subject: Window Won't Show & PopupBox Won't Close |
|
|
Hey all,
I am not sure if this is a problem with GTK or if this is expected behavior, but I would like someone's opinion. First look at the following test code:
Code: | module test;
import gtk.Main;
import gtk.MainWindow;
import gtk.Window;
import gtk.Label;
import gtk.PopupBox;
import gtk.Widget;
import gdk.Event;
import std.c.time;
import std.c.stdlib;
public class TestMainWindow : MainWindow
{
public this()
{
super("Test Window");
this.setDefaultSize(300, 250);
this.setPosition(WindowPosition.POS_CENTER);
}
//window close request
public override bool windowDelete(Event event, Widget widget)
{
if(PopupBox.yesNo(this, "Yes or No?", "Test Question"))
{
Window w = new Window("");
w.add(new Label("Please Wait..."));
w.setDefaultSize(200, 100);
w.setPosition(WindowPosition.POS_CENTER);
w.setTransientFor(this);
w.showAll;
sleep(3);
}
std.c.stdlib.exit(0); //exit the program
return false;
}
}
int main(char[][] args)
{
Main.init(args);
TestMainWindow tmw = new TestMainWindow;
tmw.showAll;
Main.run;
return 0;
} |
What I want to happen is: When the user closes the window, they get a prompt (PopupBox). If they click yes, that PopupBox will close and a new window will appear for 3 seconds. Then the program will exit.
What is happening instead, is that once they click yes, the second window never shows. The program just delays for 3 seconds and then exits.
Furthermore, if I replace the "Window w" code with a "PopupBox.information("note", "note");", the second PopupBox shows up, but when ok is clicked, it doesn't close until after the 3 seconds are up. I thought that they were supposed to close immediately after clicking sending a response.
This is so confusion, what gives?
Thanks in advance to all those who would take the time to evaluate the details of my problem. I am using: DSSS v0.78, DMD v1.053, GtkD v1.3, Ubuntu Linux 9.10.
Thanks again! _________________ わたしがプログラマだよ! |
|
Back to top |
|
|
Biga
Joined: 29 Dec 2009 Posts: 1
|
Posted: Thu Jan 21, 2010 1:08 am Post subject: |
|
|
I believe you should try attaching a callback function to the 'delete-event' singal. Depending on the response from the dialog window, your callback should return either 'true' (continue with closing the window), or 'false' (cancel delete event).
I've lurked a bit: to add the signal use 'addOnDelete' member function originated from the gtk.Widget class (which is ancestor of the gtk.Window class). |
|
Back to top |
|
|
zane.sims
Joined: 07 Aug 2007 Posts: 40
|
Posted: Thu Jan 21, 2010 5:51 am Post subject: |
|
|
If you mean instead of overriding the windowDelete method, I have already tried that as well. It gives the exact same result.
On another note: curiously, I have found that if I comment out the "std.c.stdlib.exit(0);" line, the window does show, but only AFTER the 3 seconds. I guess the window was always showing but too quickly for me to see before exiting. Still, I expected it to show before the 3 second delay...Now I am really confused?!? Does anyone have an explanation/solution? _________________ わたしがプログラマだよ! |
|
Back to top |
|
|
jpf2
Joined: 15 Aug 2009 Posts: 7
|
Posted: Thu Jan 21, 2010 8:06 am Post subject: |
|
|
I guess you shouldn't do blocking operations in the gui thread, so you cannot use sleep there. (I guess it locks the GTK main loop, so the gui can't redraw and the window can't be shown until the sleep(3) call is done.)
You would likely have to use some kind of (gtk) timer class, this seems to be the correct one: http://gtkd.mikewey.eu/src/gtk/Timeout.html
Oh, and by the way:
I think using std.c.stdlib.exit(0); is a bad practice in every d program , but it's especially bad when using gtk. You should use Main.quit() instead. |
|
Back to top |
|
|
zane.sims
Joined: 07 Aug 2007 Posts: 40
|
Posted: Thu Jan 21, 2010 12:39 pm Post subject: |
|
|
Thanks for the Main.quit advice. I was only aware of Main.exit which is now deprecated.
I was only using sleep(3); to simplify and simulate cpu processing time (probably not the best idea). My actual project requires some heavy processing after the main window is closed. I wanted to ask if they really wanted to exit, then show a "Please wait" window before and during the processing period. Then the program would exit. Since my processing prevents re-entry into the main loop, I am not sure how to attempt this.
Thanks for all your help and hopefully you or another has an idea,
Zane _________________ わたしがプログラマだよ! |
|
Back to top |
|
|
jpf2
Joined: 15 Aug 2009 Posts: 7
|
Posted: Thu Jan 21, 2010 1:38 pm Post subject: |
|
|
Well in this case you'll have to use a second thread in which you can do the processing. You have to deal with threading issues then, though. The problem is that you should not call gtk methods from any other thread than the one which called Main.run(). But I've just started with gtk/gtkd programming myself so I don't know how that should be solved, sorry. |
|
Back to top |
|
|
Mike Wey
Joined: 07 May 2007 Posts: 428
|
Posted: Thu Jan 21, 2010 3:35 pm Post subject: Re: Window Won't Show & PopupBox Won't Close |
|
|
The easiest would be to use glib.Idle or glib.Timeout to send an event to the GUI thread.
so instead of sleeping and exiting the application in the overwritten windowDelete function, you only start your thread there:
Code: | module test;
import gtk.Main;
import gtk.MainWindow;
import gtk.Window;
import gtk.Label;
import gtk.PopupBox;
import gtk.Widget;
import gdk.Event;
import std.c.time;
import std.c.stdlib;
public class TestMainWindow : MainWindow
{
public this()
{
super("Test Window");
this.setDefaultSize(300, 250);
this.setPosition(WindowPosition.POS_CENTER);
}
//window close request
public override bool windowDelete(Event event, Widget widget)
{
if(PopupBox.yesNo(this, "Yes or No?", "Test Question"))
{
Window w = new Window("");
w.add(new Label("Please Wait..."));
w.setDefaultSize(200, 100);
w.setPosition(WindowPosition.POS_CENTER);
w.setTransientFor(this);
w.showAll;
//start the processing thread.
}
return false;
}
}
int main(char[][] args)
{
Main.init(args);
TestMainWindow tmw = new TestMainWindow;
tmw.showAll;
Main.run;
return 0;
} |
and then when your done, from the thread that does the processing:
Code: |
import: glib.Idle;
import: gtk.Main;
......
new Idle(delegate bool(){ Main.quit(); })
|
The delegate is then executed by the mainloop. |
|
Back to top |
|
|
zane.sims
Joined: 07 Aug 2007 Posts: 40
|
Posted: Thu Jan 21, 2010 5:39 pm Post subject: |
|
|
Thanks Mike, and everyone else that assisted. You have solved my problem, and more importantly, I have learned more about GTK! _________________ わたしがプログラマだよ! |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|