为什么GTK(gtkmm)强迫我只创建局部变量?

时间:2017-12-26 11:44:35

标签: user-interface widget gtk global-variables gtkmm

我正在使用gtkmm为Linux编写GUI。当所有Widget对象都是本地时,程序工作正常; (在main()c ++函数内)。但是,出于我自己的目的,我想将Gtk :: Entry的对象设置为全局,以便该对象将在main方法和我自己的方法中使用,也用于on_clicked()事件方法。这是我简单代码的例子......

#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");
}

我熟悉Java Swing,所以看起来这些GTK政策对我来说非常混乱。它看起来似乎没有初始化入口变量,但我测试了非GTKMM类的其他对象,但我甚至工作使它们成为全局的。 GUI不会出现,但控制台显示一系列错误,如:

(进程:7678):Gtk-CRITICAL **:_gtk_style_cascade_get_for_screen:断言'GDK_IS_SCREEN(屏幕)'失败

最后一个错误是: (MyProg:7678):Gtk-CRITICAL **:_gtk_style_cascade_get_for_screen:断言'GDK_IS_SCREEN(屏幕)'失败 分段错误

不幸的是,我也不知道on_clicked事件方法如何使用参数,以便我可以传递甚至局部变量。

请帮帮我......

2 个答案:

答案 0 :(得分:2)

毋庸置疑,但我会不惜一切代价重复它,不惜一切代价来避免全局变量,除非你真的,真的知道你在做什么,它们是坏的并导致很多问题[1] [2] [3]。正确的方法是将小部件作为方法的参数传递  (即事件处理程序)。 This tutorial有一个如何绑定方法和信号(gtkmm使用libsigc ++)并传递额外参数的例子。

您提到的错误似乎无关,您能否提供Minimal, Complete, and Verifiable example

顺便说一下,你说你熟悉Java和Swing,GTK让你感到困惑,我不知道你的背景,但它有点像比较苹果和橘子,Java更高比C ++还要高,如果你不太了解后者,肯定会有陷阱,你最终会诅咒它和GTK。如果您没有时间或只是需要完成任务,我建议您尝试使用GTK绑定,例如Python(pygtk)或JavaScript。

答案 1 :(得分:1)

我建议制作一个允许你访问该条目的Gtk :: Window类。

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");
 ...
}

如果你想在处理程序中传递对象,那么你会做这样的事情:

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");
 ...
}