1

I'm in practice of writing GUI for Linux using gtkmm. Program works fine when all Widget objects are local; (inside main() c++ function). However, for my own purpose, I want to make object of Gtk::Entry as global so that the object will be used in both main method and my own method, and also for on_clicked() event method. This is my example of simple code......

#include <gtkmm.h>      
#include <iostream>
using namespace std;        
using namespace Gtk;        

Entry entry;   //Trying to make it visible to any block of codes
int main(){
    Main kit(argc, argv);
    Window window;
    wind.resize(300,300);

   //Widgets
   //.
   //.
   //.
   //Entry entry;   //if I create here Entry object, no runtime error!
   //but will not be accessible to other blocks.
   entry.set_text("Sample text");
   entry.show();
   //...
}


//I want the same Entry object to be accessed here
void myOwnMethod(){

entry.set_text("Updated text");
}

I'm familiar with Java Swing, so it seems these GTK policies are very confusing to me. Also it looks like entry variable is not initialized, but I tested other objects of non-GTKMM class but work even I make them to be global. GUI not appear but console display series of error like:

(process:7678): Gtk-CRITICAL **: _gtk_style_cascade_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed

the last error is: (MyProg:7678): Gtk-CRITICAL **: _gtk_style_cascade_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed Segmentation fault

Unfortunately, I dont't know also how on_clicked event method can use argument so that I can pass even local variable.

Please help me...

WailenB
  • 93
  • 7

2 Answers2

2

Needless to say, but I'll repeat it for the millionth time, avoid global variables at all costs unless you really, really know what you're doing, they are bad and cause lots of problems[1] [2] [3]. The correct approach is to pass widgets around as arguments to methods (i.e. event handlers). This tutorial has an example of how to bind methods and signals (gtkmm uses libsigc++) and pass extra arguments.

The errors you mentioned seem unrelated, could you provide a Minimal, Complete, and Verifiable example?

By the way, you said you are familiar with Java and Swing and that GTK is confusing to you, I don't know your background, but it's a bit like comparing apples and oranges, Java is higher level than C++, if you don't know the latter decently well for sure there will be pitfalls and you'll end up cursing it and GTK. If you don't have the time or just need to gets things done, I suggest you try a GTK binding such as Python(pygtk) or JavaScript.

AndreLDM
  • 2,117
  • 1
  • 18
  • 27
  • thanks for your explanation. For sure, many people suggest pyGTK or Qt based. I will try them. Javascript I use it for web, to use in desktop application development I don't know where to start. Again thank you. – WailenB Jan 01 '18 at 01:40
1

I would suggest making a Gtk::Window class that allows you to access the entry.

class MyWindow : public Gtk::Window
{
  public:
   MyWindow() { add(entry); show_all(); }
   std::string getText() { return entry.get_text(); }
   void setText(std::string s) { entry.set_text(s); }

  protected:
   Gtk::Entry entry;
   Gtk::Button button;
};

int main()
{
 MyWindow window;
 window.setText("From main");
 myOwnMethod(&window);
 return 1;
}

void myOwnMethod(MyWindow* window)
{
 ...
 window->setText("From my own method");
 ...
}

If you want to pass the object in a handler, then you would do something like this:

MyWindow::MyWindow()
{
 add(entry);
 add(button);
 button.signal_clicked().connect(sigc::bind<Gtk::Entry*>(sigc::mem_fun(*this, myOwnMethod), &entry));
 show_all();
}

void myOwnMethod(Gtk::Entry* entry)
{
 ...
 entry->set_text("From button clicked call");
 ...
}
Mark Walsh
  • 985
  • 1
  • 7
  • 12