GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Mon Oct 20, 2014 8:13 am

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Getting any signal from a closing window?
PostPosted: Sat Jul 14, 2007 7:36 pm 
Offline
Familiar Face

Joined: Thu Jul 05, 2007 6:10 pm
Posts: 9
Hello,

how can I get any signal from a (second) window I opened from another one while this second window is closed with the "X"-button of the window?
I have insufficient information about using a "window_close" event or something similar whereby you need a day or so to collect all possible events which are inherited from higher classes like GTK::widget or Gtk::Container.
For example, when I try to use the signal signal_remove from Gtk::Container, I only get while compiling stupid intern meaningless error messages like this:

Code:
$ g++ GUI*.cpp Main.cpp -o Main `pkg-config g       tkmm-2.4 --libs --cflags`
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h: In member function »typ       ename sigc::adaptor_functor<T_functor>::deduce_result_type<T_arg1, void, void, v       oid, void, void, void>::type sigc::adaptor_functor<T_functor>::operator()(T_arg1       ) const [with T_arg1 = Gtk::Widget* const&, T_functor = sigc::bound_mem_functor0       <void, GUIMenu>]«:
/usr/include/sigc++-2.0/sigc++/functors/slot.h:137:   instantiated from »static        T_return sigc::internal::slot_call1<T_functor, T_return, T_arg1>::call_it(sigc::       internal::slot_rep*, typename sigc::type_trait<T_arg3>::take) [with T_functor =        sigc::bound_mem_functor0<void, GUIMenu>, T_return = void, T_arg1 = Gtk::Widget*]       Â«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:144:   instantiated from »static        void* (* sigc::internal::slot_call1<T_functor, T_return, T_arg1>::address())(voi       d*) [with T_functor = sigc::bound_mem_functor0<void, GUIMenu>, T_return = void,        T_arg1 = Gtk::Widget*]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:529:   instantiated from »sigc::s       lot1<T_return, T_arg1>::slot1(const T_functor&) [with T_functor = sigc::bound_me       m_functor0<void, GUIMenu>, T_return = void, T_arg1 = Gtk::Widget*]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:1157:   instantiated from »sigc::       slot<T_return, T_arg1, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil, si       gc::nil>::slot(const T_functor&) [with T_functor = sigc::bound_mem_functor0<void       , GUIMenu>, T_return = void, T_arg1 = Gtk::Widget*]«
GUIMenu.cpp:72:   instantiated from here
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:84: Fehler: keine Ãœberei       nstimmung für Aufruf von »(sigc::bound_mem_functor0<void, GUIMenu>) (Gtk::Widget       * const&)«
/usr/include/sigc++-2.0/sigc++/functors/mem_fun.h:1786: Anmerkung: Kandidaten si       nd: T_return sigc::bound_mem_functor0<T_return, T_obj>::operator()() const [with        T_return = void, T_obj = GUIMenu]
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:84: Fehler: Return-Anwei       sung mit Wert in »void« zurückgebender Funktion



I used the signals like the button click signals, but here it doesn't work as you saw above.
This is the method which opens the second window. The signal connect leads to this error above.:

Code:
void GUIMenu::onInputClick()   {
    if (!isMatrixOpen)   {
        isMatrixOpen = true;
        Gtk::Window matrixWindow;
        Gtk::Table table;
         Gtk::HBox hbox;
         matrixWindow.signal_remove().connect(sigc::mem_fun(*this, &GUIMenu::onMatrixClose) );
         createTable(table);
         matrixWindow.set_title("Adjazenzmatrix");
        hbox.pack_start(table);
        matrixWindow.add(hbox);
        matrixWindow.set_resizable(false);
        matrixWindow.show_all();
       
        Gtk::Main::run(matrixWindow);
    }
}


These are the signals from the buttons of the main window added in the ctor:

Code:
    buttonInput.signal_clicked().connect(sigc::mem_fun(*this, &GUIMenu::onInputClick) );   
    buttonClose.signal_clicked().connect(sigc::mem_fun(*this, &GUIMenu::onExitClick) );   


...but they work.

My main question is how to get any signal when the second window is closed, so I don't even know if signal_remove is the right signal. I guess it isn't but I found in 2 days no information about my issue.
I hope you can help me.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 17, 2007 6:35 pm 
Offline
Familiar Face

Joined: Thu Jul 05, 2007 6:10 pm
Posts: 9
Man, that really sucks.
I didn't also get any information yet. All thousands of examples on web are just with stupid Gtk::Buttons, but there is never ever talked about connecting to a x window signal. (I guess it's a window signal).


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 17, 2007 7:12 pm 
Offline
Familiar Face

Joined: Thu Jul 05, 2007 6:10 pm
Posts: 9
By the way, I already tried signal_delete_event() which should do the right job and which is inherited from Gtk::Widget due to my logic.

http://www.gtkmm.org/docs/gtkmm-2.4/doc ... idget.html

Gtk::Window is much deeper than Gtk::Widget:

http://www.gtkmm.org/docs/gtkmm-2.4/doc ... indow.html

And I have surely a Gtk::Window:
.
.
Code:
Gtk::Window matrixWindow;
.
.
//connection a little bit later....
    matrixWindow.signal_delete_event().connect(sigc::mem_fun(*this, &GUIMenu::onMatrixClose) );   


But why the heck ends up the compiling process in crap like this:

Code:
g++ GUI*.cpp Main.cpp -o Main `pkg-config g                                      tkmm-2.4 --libs --cflags`
/usr/include/sigc++-2.0/sigc++/functors/slot.h: In static member function »stati                                      c T_return sigc::internal::slot_call1<T_functor, T_return, T_arg1>::call_it(sigc                                      ::internal::slot_rep*, typename sigc::type_trait<T_arg3>::take) [with T_functor                                       = sigc::bound_mem_functor0<void, GUIMenu>, T_return = bool, T_arg1 = GdkEventAny                                      *]«:
/usr/include/sigc++-2.0/sigc++/functors/slot.h:144:   instantiated from »static                                       void* (* sigc::internal::slot_call1<T_functor, T_return, T_arg1>::address())(voi                                      d*) [with T_functor = sigc::bound_mem_functor0<void, GUIMenu>, T_return = bool,                                       T_arg1 = GdkEventAny*]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:529:   instantiated from »sigc::s                                      lot1<T_return, T_arg1>::slot1(const T_functor&) [with T_functor = sigc::bound_me                                      m_functor0<void, GUIMenu>, T_return = bool, T_arg1 = GdkEventAny*]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:1157:   instantiated from »sigc::                                      slot<T_return, T_arg1, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil, si                                      gc::nil>::slot(const T_functor&) [with T_functor = sigc::bound_mem_functor0<void                                      , GUIMenu>, T_return = bool, T_arg1 = GdkEventAny*]«
GUIMenu.cpp:49:   instantiated from here
/usr/include/sigc++-2.0/sigc++/functors/slot.h:137: Fehler: void-Wert nicht igno                                      riert wie es sein sollte
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h: In member function »typ                                      ename sigc::adaptor_functor<T_functor>::deduce_result_type<T_arg1, void, void, v                                      oid, void, void, void>::type sigc::adaptor_functor<T_functor>::operator()(T_arg1                                      ) const [with T_arg1 = GdkEventAny* const&, T_functor = sigc::bound_mem_functor0                                      <void, GUIMenu>]«:
/usr/include/sigc++-2.0/sigc++/functors/slot.h:137:   instantiated from »static                                       T_return sigc::internal::slot_call1<T_functor, T_return, T_arg1>::call_it(sigc::                                      internal::slot_rep*, typename sigc::type_trait<T_arg3>::take) [with T_functor =                                       sigc::bound_mem_functor0<void, GUIMenu>, T_return = bool, T_arg1 = GdkEventAny*]                                      «
/usr/include/sigc++-2.0/sigc++/functors/slot.h:144:   instantiated from »static                                       void* (* sigc::internal::slot_call1<T_functor, T_return, T_arg1>::address())(voi                                      d*) [with T_functor = sigc::bound_mem_functor0<void, GUIMenu>, T_return = bool,                                       T_arg1 = GdkEventAny*]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:529:   instantiated from »sigc::s                                      lot1<T_return, T_arg1>::slot1(const T_functor&) [with T_functor = sigc::bound_me                                      m_functor0<void, GUIMenu>, T_return = bool, T_arg1 = GdkEventAny*]«
/usr/include/sigc++-2.0/sigc++/functors/slot.h:1157:   instantiated from »sigc::                                      slot<T_return, T_arg1, sigc::nil, sigc::nil, sigc::nil, sigc::nil, sigc::nil, si                                      gc::nil>::slot(const T_functor&) [with T_functor = sigc::bound_mem_functor0<void                                      , GUIMenu>, T_return = bool, T_arg1 = GdkEventAny*]«
GUIMenu.cpp:49:   instantiated from here
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:84: Fehler: keine Ãœberei                                      nstimmung für Aufruf von »(sigc::bound_mem_functor0<void, GUIMenu>) (GdkEventAny                                      * const&)«
/usr/include/sigc++-2.0/sigc++/functors/mem_fun.h:1786: Anmerkung: Kandidaten si                                      nd: T_return sigc::bound_mem_functor0<T_return, T_obj>::operator()() const [with                                       T_return = void, T_obj = GUIMenu]
/usr/include/sigc++-2.0/sigc++/adaptors/adaptor_trait.h:84: Fehler: Return-Anwei                                      sung mit Wert in »void« zurückgebender Funktion


What's going on here?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 23, 2007 7:53 pm 
Offline
Familiar Face

Joined: Thu Jul 05, 2007 6:10 pm
Posts: 9
Ok I managed this now as you can see below. Moreover you can overwrite on_delete_event too to react on a closing window. But there are even unlogical things I don't understand: cout doesn't work in the "signal methods". It's possible to set a variable but what's the difference to cout.
But the next problem is even more ridiculous. You will see why:


Code:
#include "GUIMenu.h"

GUIMenu::GUIMenu() :
    vTopBox(false, 10),
    hButtonBox(false, 10),
    hbox1(false, 10),
    hbox2(false, 10),
    hMatrixBox(false, 10),
    buttonInput("Adjazenzmatrix eingeben"),
    buttonClose("Schliessen"),
    buttonBerechnungen("Berechnungen ausgeben"),
    frameButton("Optionsmenü"),
    frameMatrix(""),
    labelSpin("Knotenanzahl: "),
    labelMatrix("Adjazenzmatrix: "),
    adjustment(3.0, 3.0, 15.0, 1.0, 5.0, 0.0),  //float value, lower, upper, step_increment page_increment, page_size
    spinbutton(adjustment),
    alignmentRight(Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER, 0.0, 0.0) {

    isMatrixWindowOpen = false;
    set_title("Graphenrechner");
    set_border_width(0);
    set_resizable(false);
    labelSpin.set_alignment(Gtk::ALIGN_LEFT);
    spinbutton.set_wrap();
    //hbox1.set_border_width(10);
    //hbox2.set_border_width(10);
    hMatrixBox.set_border_width(5);
    hButtonBox.set_border_width(5);
    vTopBox.set_border_width(5);
    hbox1.pack_start(labelSpin);
    hbox1.pack_start(spinbutton);
    hbox1.pack_start(buttonInput);
    hbox1.pack_start(buttonBerechnungen);
    alignmentRight.add(buttonClose);
    hbox2.pack_start(alignmentRight, Gtk::PACK_EXPAND_WIDGET, 50);
    hButtonBox.pack_start(hbox1);
    hButtonBox.pack_start(hbox2);
    frameButton.add(hButtonBox);
    vTopBox.pack_start(frameButton);
    //untere Hälfte einfügen
    //hMatrixBox.pack_start(labelMatrix);
    //frameMatrix.add(hMatrixBox);
    //vTopBox.pack_start(frameMatrix);
    //Top-Container dem Fenster hinzufügen
    add(vTopBox);
    //Signal setzen
    buttonInput.signal_clicked().connect(sigc::mem_fun(*this, &GUIMenu::onInputClick) );
    buttonClose.signal_clicked().connect(sigc::mem_fun(*this, &GUIMenu::onExitClick) );
    matrixWindow.signal_delete_event().connect(sigc::mem_fun(*this, &GUIMenu::onMatrixClose) );
    show_all_children();
}

GUIMenu::~GUIMenu()  {
}


void GUIMenu::onExitClick()   {
    exit(0);
}

bool GUIMenu::onMatrixClose(GdkEventAny *event)   {
    isMatrixWindowOpen = false;

    return false;
}

void GUIMenu::onInputClick()   {
    if (!isMatrixWindowOpen)   {
       createMatrixWindow();
       isMatrixWindowOpen = true;
    }
}

void GUIMenu::onMatrixClick(int j, int i, Gtk::Button *button, Gtk::Button *buttonMirror)   {
    if (i != j)   {
       if (button->get_label().compare(" 0 ") == 0)   {
          button->set_label(" 1 ");
          button->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("green"));
          if (buttonMirror != button)   {
             buttonMirror->set_label(" 1 ");
             buttonMirror->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("green"));
          }
        }
        else   {
          button->set_label(" 0 ");
          button->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("grey"));
          if (buttonMirror != button)   {
              buttonMirror->set_label(" 0 ");
              buttonMirror->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("grey"));
          }
       }
    }

}

//private
void GUIMenu::createTable(Gtk::Table &tab)   {
    //Es muss auch eine Matrix von Zeigern auf Gtk::Button erstellt werden,
    //damit man bei ungerichteten Graphen die entgegengesetzten Buttons
    //aus dem Programm ansprechen kann.
    int knotenAnzahl = spinbutton.get_value_as_int();
    Gtk::Button *pButton[knotenAnzahl][knotenAnzahl];

    for (int i = 0; i < knotenAnzahl; i++)    {
        for (int j = i; j < knotenAnzahl; j++)   {
                pButton[i][j] = Gtk::manage(new Gtk::Button(" 0 "));
                if (i == j)   {
                   pButton[i][j]->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("red"));
                   tab.attach(*pButton[i][j], j, j+1, i, i+1);
                   pButton[i][j]->signal_clicked().connect(sigc::bind<int, int>
                    (sigc::mem_fun(*this, &GUIMenu::onMatrixClick), j, i, pButton[i][j], pButton[i][j]));
                }
                else  {
                    pButton[j][i] = Gtk::manage(new Gtk::Button(" 0 "));
                    pButton[i][j]->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("grey"));
                    pButton[j][i]->modify_bg(Gtk::STATE_NORMAL, Gdk::Color("grey"));
                    tab.attach(*pButton[i][j], j, j+1, i, i+1);
                    tab.attach(*pButton[j][i], i, i+1, j, j+1);
                    pButton[i][j]->signal_clicked().connect(sigc::bind<int, int>
                    (sigc::mem_fun(*this, &GUIMenu::onMatrixClick), j, i, pButton[i][j], pButton[j][i]));
                //Umgekehrt genauso, da man sonst die Buttons auf der anderen Seite nicht klicken kann
                pButton[j][i]->signal_clicked().connect(sigc::bind<int, int>
                    (sigc::mem_fun(*this, &GUIMenu::onMatrixClick), j, i, pButton[i][j], pButton[j][i]));
                }
           }
       }
}
//private

void GUIMenu::createMatrixWindow()   {
     Gtk::Table table;
     Gtk::HBox hbox;
       
     createTable(table);
     matrixWindow.set_title("Adjazenzmatrix");
     hbox.pack_start(table);
     matrixWindow.add(hbox);
     matrixWindow.set_resizable(false);
     matrixWindow.show_all();

     Gtk::Main::run(matrixWindow);
}



buttonInput is connected to the method onInputClick(). You see the variable isMatrixWindowOpen. It's set to false in the ctor.
When I click the button which opens the matrix window, the variable shoule be and will be set to true, so that only one window can stay open at the same time.
onMatrixClose set it to false, but this method won't be even called so you can ignore it now.
When I run the program and I click "buttonInput" once, the matrix window will be opened as wished. One should think that no problems with a second window will appear if I would click the button again, because isMatrixWindowOpen is set to false, but you never guess which console error I suddendly get:

(Main:5126): Gtk-WARNING **: Attempting to add a widget with type gtkmm__GtkHBox to a gtkmm__GtkWindow, but as a GtkBin subclass a gtkmm__GtkWindow can only contain one widget at a time; it already contains a widget of type gtkmm__GtkHBox

How does this crap happen? "createMatrixWindow" WILL NOT be called in this case. So how does this message come?
Maybe it's some similar thing like the issue that you can't cout anything out of the signal methods, but already these weird program behaviours conflicts with my logic.
Either I'm blind or something similar, or gtkmm seems for me to be not technically matured yet.

Markus


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 24, 2007 1:29 pm 
Offline
Familiar Face

Joined: Thu Jul 05, 2007 6:10 pm
Posts: 9
It seems to work when I put it in the createMatrixWindow method which is invoked by the signal method.
Is there some gtkmm expert who could explain this weird behaviour?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


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 post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group