3

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.

BobMorane
  • 3,870
  • 3
  • 20
  • 42
Muh Mah
  • 35
  • 5
  • Yes. There are a number of buttons in the program that are supposed to change their location in the `Gtk::Grid` when dragging and dropping – Muh Mah Jul 26 '21 at 19:22

1 Answers1

2

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`
BobMorane
  • 3,870
  • 3
  • 20
  • 42
  • This will unrealize and realize the moved widget unnecessarily. – PBS Feb 23 '22 at 02:23
  • @PBS _unnecessarily_ : please provide an alternative solution which avoids the problem. – BobMorane Feb 23 '22 at 11:23
  • 2
    Sorry, the 'unnecessary' was referring to a problem with GTK, not your solution. There is no other way. GTK would need to add a function for it. – PBS Feb 25 '22 at 02:09