c++gtkmmgtkmm3

Move the position of a Gtk::Widget inside the Gtk::Grid


I want to move the location of two widgets inside a grid. How can I do it? What I have got so far:

        pWidget1->unparent();
        pWidget2->unparent();

        pGrid->attach(*(pWidget1), 0, 5);
        pGrid->attach(*(pWidget2), 0, 7);
        show_all();

Sadly, this code does not do what I want: the location of the widgets does not change.


Solution

  • The following example, written in Gtkmm 3.24, creates a window in which three buttons coexist inside a Gtk::Grid. clicking the Switch button will swap both A and B inside the grid. The key idea here is to

    1. Gtk::Grid::remove the widgets to move.
    2. Gtk::Grid::attach them to their new locations.

    Here is the code:

    #include <iostream>
    #include <gtkmm.h>
    
    class MainWindow : public Gtk::Window
    {
    
    public:
    
        MainWindow()
        {
            // Set buttons up:
            m_btnA.set_label("A");
            m_btnB.set_label("B");
    
            m_btnSwitch.set_label("Switch A and B");
            m_btnSwitch.signal_clicked().connect([this](){OnSwitch();});
    
            // Populate grid (initial layout):
            m_grid.attach(m_btnA, 0, 0, 1, 1);
            m_grid.attach(m_btnB, 1, 0, 1, 1);
            m_grid.attach(m_btnSwitch, 0, 1, 2, 1);
    
            // Set window up:
            add(m_grid);
            show_all();
        }
    
    private:
    
        void OnSwitch()
        {
            std::cout << "Switching A and B in grid..." << std::endl;
    
            // First, remove the buttons from the grid:
            m_grid.remove(m_btnA);
            m_grid.remove(m_btnB);
    
            // Then, re-add them in reverse order:
            if(m_aBtnFirst)
            {
                // Make "A" the second button:
                m_grid.attach(m_btnA, 1, 0, 1, 1);
                m_grid.attach(m_btnB, 0, 0, 1, 1);
            }
            else
            {
                // Make "A" the first button:
                m_grid.attach(m_btnA, 0, 0, 1, 1);
                m_grid.attach(m_btnB, 1, 0, 1, 1);
            }
    
            // Update state:
            m_aBtnFirst = !m_aBtnFirst;
    
        }
    
        Gtk::Grid m_grid;
        Gtk::Button m_btnA;
        Gtk::Button m_btnB;
    
        Gtk::Button m_btnSwitch;
    
        bool m_aBtnFirst = true;
    
    };
    
    int main(int argc, char *argv[])
    {
        auto app = Gtk::Application::create(argc, argv, "org.gtkmm.moving.grid");
      
        MainWindow window;
      
        return app->run(window);
    }
    

    Assuming you add this to a file called main.cpp, you can build it with:

    g++ main.cpp -o example.out `pkg-config --cflags --libs gtkmm-3.0`