在 gtk 中绘制背景图像 - 我的尝试都不起作用
我一直在尝试在 gtk 小部件上设置背景图像,但没有成功,即使在尝试了 4 种不同的方法之后也是如此。
下面的程序包含3种方法(第4种方法不涉及代码)。我使用 MinGW (g++ 4.5.0) 和 gtkmm 2.4 编译它。 APPROACH
宏可以设置为 1、2 或 3,以便选择编译哪种方法。我还在评论中添加了参考资料,以便您可以了解我的想法来自哪里。
#include <iostream>
#include <gtkmm/main.h>
#include <gtkmm/alignment.h>
#include <gtkmm/box.h>
#include <gtkmm/entry.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/frame.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>
#include <gtkmm/table.h>
#include <gtkmm/window.h>
// Set this to 1, 2 or 3 to try different ways of drawing the background
// Set to 0 to load no background at all
#define APPROACH (0)
// Making this alignment global in order to modify it from drawBackground
Gtk::Alignment* alignment;
bool drawBackground(GdkEventExpose* event) {
std::cout << "Draw background" << std::endl;
// Load background image
Glib::RefPtr<Gdk::Pixbuf> pixbuf = Gdk::Pixbuf::create_from_file("background.jpg");
Glib::RefPtr<Gdk::Pixmap> pixmap;
Glib::RefPtr<Gdk::Bitmap> mask;
pixbuf->render_pixmap_and_mask(pixmap, mask,0);
{
// Test that pixbuf was created correctly
Glib::RefPtr<Gdk::Pixbuf> back_to_pixbuf = Gdk::Pixbuf::create((Glib::RefPtr<Gdk::Drawable>)pixmap, 0, 0, pixbuf->get_width(), pixbuf->get_height());
back_to_pixbuf->save("back_to_pixbuf.png", "png");
}
#if APPROACH == 1
// Approach 1: draw_pixbuf
// Ref: http://islascruz.org/html/index.php/blog/show/Image-as-background-in-a-Gtk-Application..html
Glib::RefPtr<Gtk::Style> style = alignment->get_style();
alignment->get_window()->draw_pixbuf(style->get_bg_gc(Gtk::STATE_NORMAL), pixbuf, 0, 0, 0, 200, pixbuf->get_width(), pixbuf->get_height(), Gdk::RGB_DITHER_NONE, 0, 0);
#endif
#if APPROACH == 2
// Approach 2: set_back_pixmap
// Ref: http://www.gtkforums.com/viewtopic.php?t=446
// http://stackoverflow.com/questions/3150706/gtk-drawing-set-background-image
alignment->get_window()->set_back_pixmap(pixmap);
#endif
}
int main (int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
Gtk::Window w;
Gtk::VBox mainBox;
// Top image
Gtk::Image topImage("header.jpg");
mainBox.pack_start(topImage,false,false,0);
// Middle alignment
alignment = Gtk::manage(new Gtk::Alignment);
mainBox.pack_start(*alignment,true,true,0);
// Create widget
Gtk::Alignment mywidget(0.5, 0.5, 0.1, 0.9);
Gtk::Table table;
Gtk::Label label1("Username"); table.attach(label1,0,1,0,1);
Gtk::Label label2("Password"); table.attach(label2,0,1,1,2);
Gtk::Entry entry1; table.attach(entry1,1,2,0,1);
Gtk::Entry entry2; table.attach(entry2,1,2,1,2);
Gtk::Button button("Login"); table.attach(button,1,2,2,3);
mywidget.add(table);
// Put widget in middle alignment
alignment->add(mywidget);
// Try to change the background
#if APPROACH == 1 || APPROACH == 2
alignment->signal_expose_event().connect(sigc::ptr_fun(&drawBackground), true);
#endif
#if APPROACH == 3
// Approach 3: modify the style using code
// Ref: http://www.gtkforums.com/viewtopic.php?t=446
// Load background image
Glib::RefPtr<Gdk::Pixbuf> pixbuf = Gdk::Pixbuf::create_from_file("background.jpg");
Glib::RefPtr<Gdk::Pixmap> pixmap;
Glib::RefPtr<Gdk::Bitmap> mask;
pixbuf->render_pixmap_and_mask(pixmap, mask,0);
Glib::RefPtr<Gtk::Style> style = alignment->get_style()->copy();
style->set_bg_pixmap(Gtk::STATE_NORMAL,pixmap);
style->set_bg_pixmap(Gtk::STATE_ACTIVE,pixmap);
style->set_bg_pixmap(Gtk::STATE_PRELIGHT,pixmap);
style->set_bg_pixmap(Gtk::STATE_SELECTED,pixmap);
style->set_bg_pixmap(Gtk::STATE_INSENSITIVE,pixmap);
alignment->set_style(style);
#endif
// Approach 4: modify share\themes\MS-Windows\gtk-2.0
// adding the following line
// bg_pixmap[NORMAL] = "D:\\path\\to\\file\\background.jpg"
// in the style "msw-default" section
// Ref: http://lists.ximian.com/pipermail/gtk-sharp-list/2005-August/006324.html
// Show the window
w.add(mainBox);
w.show_all();
kit.run(w);
return 0;
}
我使用的图像链接: header.jpg background.jpg
布局模仿了我的实际程序。主窗口包含一个 Gtk::VBox,顶部有标题图像,底部有 Gtk::Alignment。此对齐的内容会随着时间的推移而改变,但我希望它有一个始终可见的背景图像。
当根本不加载背景时,标题图像会正确加载,窗口如下所示:
方法 1 是一种更接近工作的方法,尽管它隐藏了标签和按钮:
方法2 和 3 看起来与不加载背景相同。此外,方法 2 给了我以下错误消息:
(test-img-fondo.exe:1752): Gdk-CRITICAL **: gdk_window_set_back_pixmap: assertion `pixmap == NULL || !parent_relative' failed
添加以下行来修改 share\themes\MS-Windows\gtk-2.0
bg_pixmap[NORMAL] = "D:\\path\\to\\file\\background.jpg"
最后,在方法 4 中,我尝试通过在样式“msw-”中 默认”部分。它也不起作用。
那么,有人成功地在 Gtk 小部件上绘制了背景图像吗?这有可能吗?我的代码中是否有任何更改可以使此工作正常进行?有什么解决方法吗?
非常感谢所有帮助。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想我自己已经解决了。使用方法 1,但更改此行
:
这样,对 drawBackground 的调用发生在 gtk 调用其自己的处理程序之前。
我还应该指出,在真实的程序中,图像应该在
绘制背景
。I think I've solved it myself. Use approach 1 but change this line
for this:
This way, the call to drawBackground occurs before gtk calls its own handlers.
I should also point out that, in a real program, the images should be loaded once outside of
drawBackground
.