简体   繁体   中英

How to access GTKMM widgets from other file?

I have a simple gtk+ application made with gtkmm, and I want to change the content of the window when I press a button, and I want to put that code in a seperate file (changeTitle.cc). How do I access the "buttons" object from that file?

main.cc:

#include <iostream>
#include "buttons.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
Glib::RefPtr<Gtk::Application> app =
Gtk::Application::create(argc, argv,
  "org.gtkmm.examples.base");

Buttons buttons;


return app->run(buttons);

}

buttons.h:

#ifndef GTKMM_EXAMPLE_BUTTONS_H
#define GTKMM_EXAMPLE_BUTTONS_H

#include <gtkmm/window.h>
#include <gtkmm/button.h>
#include <gtkmm/box.h>

class Buttons : public Gtk::Window
{
public:
Buttons();

virtual ~Buttons();

protected:
//Signal handlers:
void on_button_clicked();

//Child widgets:
Gtk::Button m_button;
Gtk::Box buttonBox;
};

#endif //GTKMM_EXAMPLE_BUTTONS_H  

buttons.cc:

#include <iostream>
#include <stdlib.h>
#include "buttons.h"
#include "changeTitle.h"

Buttons::Buttons()
{
m_button.add_pixlabel("info.xpm", "click here");

set_title("Menu");
set_border_width(10);

m_button.signal_clicked().connect( sigc::mem_fun(*this,
          &Buttons::on_button_clicked) );

add(buttonBox);

buttonBox.pack_start(m_button);

show_all_children();
}

Buttons::~Buttons()
{

}

void Buttons::on_button_clicked()
{
changeTitle();
}

changeTitle.h:

void changeTitle();

changeTitle.cc:

#include "changeTitle.h"

void changeTitle()
{
    buttons.set_title("new title");
}

This isn't specific to gtkmm at all. I wonder if you would benefit from some simple, non-GUI examples to improve your grasp of object scope, before pulling complex libraries into the equation to muddy the waters.

Problem

Accessing buttons directly from anywhere except within main() cannot be done with your present architecture. buttons is a local object scoped in main() . It is not available to any other function, never mind any other translation unit (basically, file) - by which I mean they can't just refer to it by name. If you want them to use it, you have to pass it to them, or otherwise relax its scope such that they can pull it... more on that next.

[ Indenting your code properly would probably help you grok things more visually, including the issue of scope. ]

Solution

So, with buttons as with any other scoped object, you either need to pass the object to any function that uses it, put all such functions within a class and make the object a member variable , or - perish the thought - use a global variable.

The simplest option is putting your 'change title' logic right in your signal-clicked handler, letting it access the current this instance of Buttons (really Window s; confusing name you chose) - which, handily, is the same one whose actual Gtk::Button emitted the click. Is there a reason you left changeTitle() as a free function that attempts to refer to one particular, other instance of Buttons ?

If you could do this, say you created multiple Buttons es - let's call them A, B, and C - clicking the button in any would call changeTitle() on a different Buttons instance in main() ... which seems weird. You can split class member definitions across multiple source files, by the way, if you didn't know.

So, clearly, some redesign is required. Which of these options you chose depends on how you want your program and its data to be organised. If none of this is on the right track, then you'd need to explain what you want further.

And I'll say it: Don't use a global variable... unless you have a very good justification. There are some, but not many. They're not quite as bad as a lot of people make out, but due to the diagnostic and maintenance headaches they risk opening up, nor should you use one without a good justification; they should not be a first option.

Unaffiliated gushing

Btw, I love gtkmm , can't promote it enough. It's a fantastic project with great steering, which I think is woefully unsung in the larger 'community'. But again, it's orthogonal to the basic issue here, which is simple object scoping.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM