[Gtk-sharp-list] reusing windows using attribute [Widget]
Nigel Benns
nigel_benns@rogers.com
Thu, 9 Dec 2004 10:40:34 -0500 (EST)
Hi Javier,
This is caused because after you destroy and object you need to reload
its information from glade again, as it only binds to the objects after
the Autoconnect(this)
If you have to destroy your window, redo the:
Glade.XML gxml = new Glade.XML (null, "gui.glade", null, null);
gxml.Autoconnect (this); //you might be able to get away with just
this, I haven't tested it tho.
The better idea in this situation would be to do what Francis was
suggesting and use Show and Hide.
It would be a better implementation to wrap the seperate window in its
own class as Francis suggested as well. This would allow your program to
create multiple instances of the window (if you want that).
//From here on is probably a whole bunch of crap you don't needed :P
//But I'm bored!
If you don't want that, make the class a Singleton.
eg:
public class Window2 {
private static Window2 win; //Keep the real instance private
[Widget] Window window2; //The actual Gtk.Window from glade
private static Object lockObject = "Lock";
private Window2() {
Glade.XML gxml = new Glade.XML (null, "gui.glade", null, null);
gxml.Autoconnect (this);
}
public static Window2 Instance {
get {
//This is what guarantees that only one window will be created.
lock(lockObject) { //Just in case it gets called at the same time
if (win == null) win = new Window2();
}
return win;
}
}
public void Show() {
window2.ShowAll();
}
private void OnWindowDeleteEvent (object o, DeleteEventArgs args) {
window2.Hide();
}
}
and then to use it like:
public void on_button1_clicked (object o, EventArgs args)
{
Window2 tmpWin = Window2.Instance;
tmpWin.Show();
}
I'm doing this off the top of my head right now, so if it doesn't work
right off (and you actually want to use this :P) then send me back a
reply if you can't fix it.
Now another idea as well that will work if you want to get the result of
a window and don't want to leave the function your are in, say for
entering a username and password for authentication before a required
action (which is exactly what I use it for).
Just slightly modify the Singleton class:
public class AuthUser {
private static AuthUser authUser; //Keep the real instance private
private static Object lockObject = "Lock";
private static string username = "", password = "";
[Widget] Dialog dlgAuth; // A Dialog with Ok, Cancel and 2 Entries
[Widget] Entry entUser, entPass;
private AuthUser() {
}
public static AuthUser Instance {
get {
//This is what guarantees that only one window will be created.
lock(lockObject) { //Just in case it gets called at the same time
if (win == null) win = new Window2();
}
return win;
}
}
public string Username {
get {
return username;
}
}
public string Password {
get {
return password;
}
}
public void Authenticate() {
Application.Init();
Glade.XML gxml = new Glade.XML (null, "gui.glade", null, null);
gxml.Autoconnect (this);
dlgAuth.ShowAll();
Application.Run();
}
public void btnOkClicked (object o, EventArgs args) {
username = entUser.Text;
password = entPass.Text;
Application.Quit();
}
private void OnWindowDeleteEvent (object o, DeleteEventArgs args) {
Application.Quit();
}
}
Use this like:
bool authorized = true;
AuthUser tmpUser = AuthUser.Instance;
try {
//Check your authorization(assuming an error is thrown if your not
authorized)
}
catch {
authorized = false;
}
while(!authorized) {
tmpUser.Authenticate();
/*Check the authorization again using:
tmpUser.Username and tmpUser.Password
and then set authorized = true if we are authorized;
}
Its not perfect because I left out some stuff, but now you have a class
that an entire program can use to graphically authenticate whenever
needed. And because it runs within its own gtk_main_loop() it doesn't have
to wait for your application to be idle before it loads.
Now wasn't that a complete waist of time :)
> Hey
>
> I have the following program:
> ----------
> using System;
> using Gtk;
> using Glade;
>
> public class GladeApp
> {
> [Widget] Gtk.Window window1;
> [Widget] Gtk.Window window2;
> [Widget] Gtk.Button button1;
>
> public static void Main (string[] args)
> {
> new GladeApp (args);
> }
> public GladeApp (string[] args)
> {
> Application.Init();
> Glade.XML gxml = new Glade.XML (null, "gui.glade", null, null);
> gxml.Autoconnect (this);
> Application.Run();
> }
> public void OnWindowDeleteEvent (object o, DeleteEventArgs args)
> {
> Application.Quit ();
> args.RetVal = true;
> }
> public void on_button1_clicked (object o, EventArgs args)
> {
> window2.Visible = true;
> }
> }
> ----------
> gui.glade has two windows, "window1" and "window2"; "window1" has one
> button "button1"; "button1" has one signal "on_button1_clicked" and
> "window2" is not visible by default.
>
> The idea, is to have an event on "window1" that opens "window2"
>
> It work very well for me the first time, the problem comes when I close
> "window2", the window is destroyed and when I click on "button1" again
> to re-open "window2", it is empty.
>
> I have two ideas of how to work around this issue (please correct me if
> I'm wrong)
>
> 1.- to have another class (one class per window) with it's own:
>
> Glade.XML gxml = new Glade.XML (null, "gui.glade", "window2", null);
>
> and instance this class every time I want to open "window2"
>
> 2.- to use gxml.GetWidget("window2"); I don't like this one 'cause
> GetWidget returns an object of type Gtk.Widget :(
>
> Is there any way to re-open window2 also using the arrtribute [Widget]?
> i.e. by not destroying the window, or re-instance it a second time ?
>
>
> Thanks
> --
> Javier Díaz <javierdiazm@yahoo.com.mx>
>
> _______________________________________________
> Gtk-sharp-list maillist - Gtk-sharp-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/gtk-sharp-list
>