为什么 GTK (gtkmm) 只强制我创建局部变量?
Why GTK (gtkmm) forces me only to create local variable?
我正在练习使用 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 class 的其他对象,但即使我使它们成为全局对象也能正常工作。 GUI 未出现,但控制台显示一系列错误,如:
(process:7678): Gtk-CRITICAL **: _gtk_style_cascade_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
最后一个错误是:
(MyProg:7678): Gtk-CRITICAL **: _gtk_style_cascade_get_for_screen: 断言 'GDK_IS_SCREEN (screen)' 失败
分段错误
不幸的是,我也不知道 on_clicked
事件方法如何使用参数,以便我什至可以传递局部变量。
请帮帮我...
不用说,但我会重复百万次,不惜一切代价避免使用全局变量,除非你真的、真的知道自己在做什么,它们是不好并导致很多问题[1] [2] [3]。正确的方法是将小部件作为参数传递给方法
(即事件处理程序)。 This tutorial 有一个示例说明如何绑定方法和信号(gtkmm 使用 libsigc++)并传递额外的参数。
你提到的错误似乎无关,你能提供一个Minimal, Complete, and Verifiable example吗?
对了,你说你熟悉Java和Swing,GTK让你很困惑,我不知道你的背景,但有点像拿苹果和橘子比较,Java 比 C++ 更高级别,如果你不太了解后者,肯定会有陷阱,你最终会诅咒它和 GTK。如果您没有时间或只是需要完成任务,我建议您尝试使用 GTK 绑定,例如 Python(pygtk) 或 JavaScript.
我建议制作一个 Gtk::Window class 以允许您访问该条目。
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");
...
}
我正在练习使用 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 class 的其他对象,但即使我使它们成为全局对象也能正常工作。 GUI 未出现,但控制台显示一系列错误,如:
(process:7678): Gtk-CRITICAL **: _gtk_style_cascade_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
最后一个错误是: (MyProg:7678): Gtk-CRITICAL **: _gtk_style_cascade_get_for_screen: 断言 'GDK_IS_SCREEN (screen)' 失败 分段错误
不幸的是,我也不知道 on_clicked
事件方法如何使用参数,以便我什至可以传递局部变量。
请帮帮我...
不用说,但我会重复百万次,不惜一切代价避免使用全局变量,除非你真的、真的知道自己在做什么,它们是不好并导致很多问题[1] [2] [3]。正确的方法是将小部件作为参数传递给方法 (即事件处理程序)。 This tutorial 有一个示例说明如何绑定方法和信号(gtkmm 使用 libsigc++)并传递额外的参数。
你提到的错误似乎无关,你能提供一个Minimal, Complete, and Verifiable example吗?
对了,你说你熟悉Java和Swing,GTK让你很困惑,我不知道你的背景,但有点像拿苹果和橘子比较,Java 比 C++ 更高级别,如果你不太了解后者,肯定会有陷阱,你最终会诅咒它和 GTK。如果您没有时间或只是需要完成任务,我建议您尝试使用 GTK 绑定,例如 Python(pygtk) 或 JavaScript.
我建议制作一个 Gtk::Window class 以允许您访问该条目。
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");
...
}