本文介绍了如何在Linux上使gtkwindow背景透明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 以下是我的代码: #include< gtk / gtk.h> int main(int argc,char * argv []) { gtk_init(& argc,& argv); GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL); //标题 gtk_window_set_title(GTK_WINDOW(window),透明度); // gtk_window_set_opacity(GTK_WINDOW(window),0.5); // CSS GtkCssProvider * provider = gtk_css_provider_new(); GdkDisplay * display = gdk_display_get_default(); GdkScreen * screen = gdk_display_get_default_screen(display); gtk_style_context_add_provider_for_screen(screen,GTK_STYLE_PROVIDER(provider),GTK_STYLE_PROVIDER_PRIORITY_USER); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(provider),GtkWindow {\ nbackground-color:rgba(0,0,0,0); \\\ } \\\, -1,NULL); g_object_unref(provider); // Window gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); gtk_window_resize(GTK_WINDOW(window),400,300); gtk_widget_show_all(window); gtk_main(); 返回0; } 我使用gtk3。程序执行时,只显示黑色。 CSS(或rgba)函数不起作用。 我尝试使用gtk_window_set_opacity(),但它也只显示黑色。 我该如何修复我的代码? 我遵循链接,但不幸的是它是为Gtk 2编写的。我已经为Gtk 3重新开发了它。 (我使用的是Gtk 3.8,但据我所知它不使用任何在Gtk 3.10中弃用的东西)。该程序产生一个绿色半透明的方形按钮。当然,通过将函数 cairo_set_source_rgba 的最后一个参数更改为0,可以使方块完全透明。 注意:我用下面的命令编译了这个文件(假设你调用文件 transparent.c ): gcc -otransparent transparent.c`pkg-config gtk + -3.0 --libs --cflags` 以下是代码: 版本C / ** *原始代码作者:Mike - http://plan99.net/~mike/blog(现在是一个死链接 - 无法找到它)。 *由karlphillip修改为StackExchange: *(https://stackoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent) * 2014年1月30日,LC,Louis Melahn为Gtk 3工作。 * / #include< gtk / gtk.h> static void screen_changed(GtkWidget * widget,GdkScreen * old_screen,gpointer user_data); static gboolean draw(GtkWidget * widget,cairo_t * new_cr,gpointer user_data); static void clicked(GtkWindow * win,GdkEventButton * event,gpointer user_data); $ b $ int main(int argc,char ** argv) { gtk_init(& argc,& argv); GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window),400,400); gtk_window_set_title(GTK_WINDOW(window),Alpha Demo); g_signal_connect(G_OBJECT(window),delete-event,gtk_main_quit,NULL); gtk_widget_set_app_paintable(window,TRUE); g_signal_connect(G_OBJECT(window),draw,G_CALLBACK(draw),NULL); g_signal_connect(G_OBJECT(window),screen-changed,G_CALLBACK(screen_changed),NULL); gtk_window_set_decorated(GTK_WINDOW(window),FALSE); gtk_widget_add_events(window,GDK_BUTTON_PRESS_MASK); g_signal_connect(G_OBJECT(window),button-press-event,G_CALLBACK(clicked),NULL); GtkWidget * fixed_container = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window),fixed_container); GtkWidget * button = gtk_button_new_with_label(button1); gtk_widget_set_size_request(button,100,100); gtk_container_add(GTK_CONTAINER(fixed_container),button); screen_changed(window,NULL,NULL); gtk_widget_show_all(window); gtk_main(); 返回0; } gboolean supports_alpha = FALSE; static void screen_changed(GtkWidget * widget,GdkScreen * old_screen,gpointer userdata) { / *要检查显示器是否支持Alpha通道,请获取可视* / GdkScreen * screen = gtk_widget_get_screen(widget); GdkVisual * visual = gdk_screen_get_rgba_visual(screen); if(!visual) { printf(您的屏幕不支持alpha通道!\ n); visual = gdk_screen_get_system_visual(screen); supports_alpha = FALSE; } else { printf(你的屏幕支持alpha通道!\\\); supports_alpha = TRUE; } gtk_widget_set_visual(widget,visual); static gboolean draw(GtkWidget * widget,cairo_t * cr,gpointer userdata) { cairo_t * new_cr = gdk_cairo_create(gtk_widget_get_window(widget)); if(supports_alpha) { cairo_set_source_rgba(new_cr,0.5,1.0,0.50,0.5); / *透明* / } else { cairo_set_source_rgb(new_cr,1.0,1.0,1.0); / *不透明白* / } / *绘制背景* / cairo_set_operator(new_cr,CAIRO_OPERATOR_SOURCE); cairo_paint(new_cr); cairo_destroy(new_cr); 返回FALSE; static void clicked(GtkWindow * win,GdkEventButton * event,gpointer user_data) { / *切换窗口管理器帧* / gtk_window_set_decorated (win,!gtk_window_get_decorated(win)); code C ++版本 我包含一个非常类似的程序,这次是用C ++编写的 gtkmm 。它可以使用以下命令编译: g ++ -otransparent main.cpp transparent.cpp`pkg-config gtkmm-3.0 - -cflags --libs` -std = c ++ 11 请注意,我使用了一些功能在新的C ++ - 11标准中,所以你需要一个支持它们的编译器。 (如果你没有,你只需要用适当的类型替换 auto 关键字,你可以从函数的定义中找到它。 )有三个文件: main.cpp , transparent.h 和 transparent.cpp 。 main.cpp / ** * main.cpp * *代码由'alphademo.c'由Mike *修改(http:// plan99。 net /〜mike / blog - 现在是死链接 - 无法找到它。) *由karlphillip修改为StackExchange: *(https://stackoverflow.com/questions/3908565/怎么做 - gtk-window-background-transparent) *通过Louis Melahn重新为Gtkmm 3.0工作,LC 2014年1月31日。 * / #includetransparent.h #include< gtkmm / application.h> int main(int argc,char * argv []) { Glib :: RefPtr< Gtk :: Application> app = Gtk :: Application :: create(argc,argv,org.gtkmm.example.transparent); 透明透明; //显示窗口并在关闭时返回。 return app-> run(transparent); } transparent.h / ** * transparent.h * *代码由'alphademo.c'改编,由Mike *(http://plan99.net/~mike/blog--现在是死链接 - 无法找到它)。 *由karlphillip修改为StackExchange: *(https ://backoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent) *由Louis Melahn,LC重新为Gtkmm 3.0工作2014年1月31日。 * / #ifndef TRANSPARENT_H_ #define TRANSPARENT_H_ #include< iostream> #include< gtk / gtk.h> #include< gtkmm / window.h> #include< gtkmm / button.h> #include< gtkmm / alignment.h> 类透明:public Gtk :: Window { private: std :: string _buttonLabel; public: Transparent(); void set_visual(Glib :: RefPtr< Gdk :: Visual> visual); virtual〜Transparent(); protected: //信号处理程序: //请注意,on_draw实际上是从Gtk :: Window类重写一个虚函数 //。我将它设置为虚拟的以防 //有人想要在派生类中重新覆盖它。 void on_button_clicked(); virtual bool on_draw(const :: Cairo :: RefPtr< :: Cairo :: Context>& cr); void on_screen_changed(const Glib :: RefPtr< Gdk :: Screen>& previous_screen); bool on_window_clicked(GdkEventButton * event); //会员小部件: Gtk :: Alignment _alignment; Gtk :: Button _button; bool _SUPPORTS_ALPHA = false; }; #endif / * TRANSPARENT_H_ * / transparent.cpp / ** * transparent.cpp * * Code改编自'alphademo.c'by Mike *(http://plan99.net/~mike/blog--现在是死链接 - 无法找到它)。 *由karlphillip修改对于StackExchange: *(https://stackoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent) *由Louis Melahn重新为Gtkmm 3.0工作, LC 2014年1月31日。 * / #includetransparent.h Transparent :: Transparent(): _buttonLabel(Button1), _alignment(Gtk :: ALIGN_START,Gtk :: ALIGN_START,0.0,0.0),//对齐按钮。 _button(_buttonLabel)//创建一个标签为'_buttonLabel'的新按钮。 { //设置顶层窗口。 set_title(透明度测试); set_default_size(400,400); set_decorated(false); add_events(Gdk :: BUTTON_PRESS_MASK); set_position(Gtk :: WIN_POS_CENTER); set_app_paintable(true); //信号处理程序 signal_draw()。connect(sigc :: mem_fun(* this,& Transparent :: on_draw)); signal_screen_changed()。connect(sigc :: mem_fun(* this,& Transparent :: on_screen_changed)); signal_button_press_event()。connect(sigc :: mem_fun(* this,& Transparent :: on_window_clicked)); _button.signal_clicked()。connect(sigc :: mem_fun(* this,& Transparent :: on_button_clicked)); //小工具 on_screen_changed(get_screen()); //这将添加对齐器。 add(_alignment); //现在将按钮装入对齐器。 _alignment.add(_button); //设置按钮 _button.set_size_request(100,100); //显示窗口及其所有子项。 show_all(); } Transparent ::〜Transparent() {} void Transparent :: on_button_clicked() { std :: cout<< 按钮'<< _buttonLabel<< '被按下了。 <<的std :: ENDL; bool Transparent :: on_draw(const Cairo :: RefPtr< Cairo :: Context>& cr) { cr-> save() ; (_SUPPORTS_ALPHA){ cr-> set_source_rgba(0.5,1.0,0.5,0.5); 。 //透明} else { cr-> set_source_rgb(0.5,1.0,0.5); // opaque } cr-> set_operator(Cairo :: OPERATOR_SOURCE); cr-> paint(); cr-> restore(); return Gtk :: Window :: on_draw(cr); } $ b $ ** ** b $ b *检查显示器是否支持alpha通道 * / void Transparent :: on_screen_changed(const Glib :: RefPtr< Gdk :: Screen>& previous_screen){ auto screen = get_screen(); auto visual = screen-> get_rgba_visual(); if(!visual){ std :: cout<< 你的屏幕不支持Alpha通道! <<的std :: ENDL; } else { std :: cout<< 你的屏幕支持alpha通道! <<的std :: ENDL; _SUPPORTS_ALPHA = TRUE; } set_visual(visual); } / ** *这只是增加了一个在Gtk :: Widget中缺少的方法, *因此我不得不手动使用Gtk +。 * *为'this'(当前小部件)设置可视化。 * / void Transparent :: set_visual(Glib :: RefPtr< Gdk :: Visual> visual){ gtk_widget_set_visual(GTK_WIDGET(gobj()),visual-> gobj()) ; } $ b $ ** / ** *如果我点击按钮以外的其他位置,这会在装饰窗口和没有窗口装饰之间切换 *。 * / bool Transparent :: on_window_clicked(GdkEventButton * event){ set_decorated(!get_decorated()); 返回false; } 希望这有助于您! I would like to make the background transparent, and only the widgets are visible.Here is my code:#include <gtk/gtk.h>int main (int argc, char *argv[]){ gtk_init (&argc, &argv); GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); // Title gtk_window_set_title(GTK_WINDOW (window), "Transparency"); //gtk_window_set_opacity(GTK_WINDOW(window), 0.5); // CSS GtkCssProvider *provider = gtk_css_provider_new(); GdkDisplay *display = gdk_display_get_default(); GdkScreen *screen = gdk_display_get_default_screen(display); gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER (provider), "GtkWindow {\n" " background-color: rgba(0,0,0,0);\n" "}\n", -1, NULL); g_object_unref (provider); // Window gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_resize(GTK_WINDOW(window), 400, 300); gtk_widget_show_all(window); gtk_main(); return 0;}I use gtk3. When the program execute, it just shows black. The CSS (or rgba) function does not work.I try to use gtk_window_set_opacity(), but it also just shows black.How do I fix my code? 解决方案 I followed the link suggested by the comment, but unfortunately it was written for Gtk 2. I have re-worked it for Gtk 3. (I am using Gtk 3.8, but as far as I know it does not use anything deprecated in Gtk 3.10). The program produces a green semi-transparent square with button in it. Of course, you could make the square completely transparent by changing the last argument for the function cairo_set_source_rgba to 0.Note: I compiled this with the following command (assuming you call the file transparent.c):gcc -otransparent transparent.c `pkg-config gtk+-3.0 --libs --cflags`Here is the code:Version for C/** * Original code by: Mike - http://plan99.net/~mike/blog (now a dead link--unable to find it). * Modified by karlphillip for StackExchange: * (https://stackoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent) * Re-worked for Gtk 3 by Louis Melahn, L.C., January 30, 2014. */#include <gtk/gtk.h>static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer user_data);static gboolean draw(GtkWidget *widget, cairo_t *new_cr, gpointer user_data);static void clicked(GtkWindow *win, GdkEventButton *event, gpointer user_data);int main(int argc, char **argv){ gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 400, 400); gtk_window_set_title(GTK_WINDOW(window), "Alpha Demo"); g_signal_connect(G_OBJECT(window), "delete-event", gtk_main_quit, NULL); gtk_widget_set_app_paintable(window, TRUE); g_signal_connect(G_OBJECT(window), "draw", G_CALLBACK(draw), NULL); g_signal_connect(G_OBJECT(window), "screen-changed", G_CALLBACK(screen_changed), NULL); gtk_window_set_decorated(GTK_WINDOW(window), FALSE); gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK); g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(clicked), NULL); GtkWidget* fixed_container = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window), fixed_container); GtkWidget* button = gtk_button_new_with_label("button1"); gtk_widget_set_size_request(button, 100, 100); gtk_container_add(GTK_CONTAINER(fixed_container), button); screen_changed(window, NULL, NULL); gtk_widget_show_all(window); gtk_main(); return 0;}gboolean supports_alpha = FALSE;static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer userdata){ /* To check if the display supports alpha channels, get the visual */ GdkScreen *screen = gtk_widget_get_screen(widget); GdkVisual *visual = gdk_screen_get_rgba_visual(screen); if (!visual) { printf("Your screen does not support alpha channels!\n"); visual = gdk_screen_get_system_visual(screen); supports_alpha = FALSE; } else { printf("Your screen supports alpha channels!\n"); supports_alpha = TRUE; } gtk_widget_set_visual(widget, visual);}static gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer userdata){ cairo_t *new_cr = gdk_cairo_create(gtk_widget_get_window(widget)); if (supports_alpha) { cairo_set_source_rgba (new_cr, 0.5, 1.0, 0.50, 0.5); /* transparent */ } else { cairo_set_source_rgb (new_cr, 1.0, 1.0, 1.0); /* opaque white */ } /* draw the background */ cairo_set_operator (new_cr, CAIRO_OPERATOR_SOURCE); cairo_paint (new_cr); cairo_destroy(new_cr); return FALSE;}static void clicked(GtkWindow *win, GdkEventButton *event, gpointer user_data){ /* toggle window manager frames */ gtk_window_set_decorated(win, !gtk_window_get_decorated(win));}Version for C++I include a very similar program, this time written for gtkmm in C++. It can be compiled with the following command:g++ -otransparent main.cpp transparent.cpp `pkg-config gtkmm-3.0 --cflags --libs` -std=c++11Note that I used some of the features in the new C++-11 standard, so you will need a compiler that supports them. (If you don't have one, you just have to replace the auto keyword when it appears with the appropriate type, which you can figure out from the definition of the function.) There are three files: main.cpp, transparent.h, and transparent.cpp.main.cpp/** * main.cpp * * Code adapted from 'alphademo.c' by Mike * (http://plan99.net/~mike/blog--now a dead link--unable to find it.) * as modified by karlphillip for StackExchange: * (https://stackoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent) * Re-worked for Gtkmm 3.0 by Louis Melahn, L.C. January 31, 2014. */#include "transparent.h"#include <gtkmm/application.h>int main (int argc, char *argv[]){ Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example.transparent"); Transparent transparent; //Shows the window and returns when it is closed. return app->run(transparent);}transparent.h/** * transparent.h * * Code adapted from 'alphademo.c' by Mike * (http://plan99.net/~mike/blog--now a dead link--unable to find it.) * as modified by karlphillip for StackExchange: * (https://stackoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent) * Re-worked for Gtkmm 3.0 by Louis Melahn, L.C. January 31, 2014. */#ifndef TRANSPARENT_H_#define TRANSPARENT_H_#include <iostream>#include <gtk/gtk.h>#include <gtkmm/window.h>#include <gtkmm/button.h>#include <gtkmm/alignment.h>class Transparent : public Gtk::Window{private: std::string _buttonLabel;public: Transparent(); void set_visual(Glib::RefPtr<Gdk::Visual> visual); virtual ~Transparent();protected: // Signal handlers: // Note that on_draw is actually overriding a virtual function // from the Gtk::Window class. I set it as virtual here in case // someone wants to override it again in a derived class. void on_button_clicked(); virtual bool on_draw(const ::Cairo::RefPtr< ::Cairo::Context>& cr); void on_screen_changed(const Glib::RefPtr<Gdk::Screen>& previous_screen); bool on_window_clicked(GdkEventButton* event); // Member widgets: Gtk::Alignment _alignment; Gtk::Button _button; bool _SUPPORTS_ALPHA = false;};#endif /* TRANSPARENT_H_ */transparent.cpp/** * transparent.cpp * * Code adapted from 'alphademo.c' by Mike * (http://plan99.net/~mike/blog--now a dead link--unable to find it.) * as modified by karlphillip for StackExchange: * (https://stackoverflow.com/questions/3908565/how-to-make-gtk-window-background-transparent) * Re-worked for Gtkmm 3.0 by Louis Melahn, L.C. January 31, 2014. */#include "transparent.h"Transparent::Transparent() : _buttonLabel("Button1"), _alignment(Gtk::ALIGN_START, Gtk::ALIGN_START, 0.0, 0.0), // Aligns the button. _button(_buttonLabel) // Creates a new button with label '_buttonLabel'.{ // Set up the top-level window. set_title("Transparency test"); set_default_size(400,400); set_decorated(false); add_events(Gdk::BUTTON_PRESS_MASK); set_position(Gtk::WIN_POS_CENTER); set_app_paintable(true); // Signal handlers signal_draw().connect(sigc::mem_fun(*this, &Transparent::on_draw)); signal_screen_changed().connect(sigc::mem_fun(*this, &Transparent::on_screen_changed)); signal_button_press_event().connect(sigc::mem_fun(*this, &Transparent::on_window_clicked)); _button.signal_clicked().connect(sigc::mem_fun(*this, &Transparent::on_button_clicked)); // Widgets on_screen_changed(get_screen()); // This will add the aligner. add(_alignment); // Now pack the button into the aligner. _alignment.add(_button); // Set up the button _button.set_size_request(100, 100); // Show the window and all its children. show_all();}Transparent::~Transparent(){}void Transparent::on_button_clicked(){ std::cout << "The button '" << _buttonLabel << "' was pressed." << std::endl;}bool Transparent::on_draw(const Cairo::RefPtr<Cairo::Context>& cr){ cr->save(); if (_SUPPORTS_ALPHA) { cr->set_source_rgba(0.5, 1.0, 0.5, 0.5); // transparent } else { cr->set_source_rgb(0.5, 1.0, 0.5); // opaque } cr->set_operator(Cairo::OPERATOR_SOURCE); cr->paint(); cr->restore(); return Gtk::Window::on_draw(cr);}/** * Checks to see if the display supports alpha channels */void Transparent::on_screen_changed(const Glib::RefPtr<Gdk::Screen>& previous_screen) { auto screen = get_screen(); auto visual = screen->get_rgba_visual(); if (!visual) { std::cout << "Your screen does not support alpha channels!" << std::endl; } else { std::cout << "Your screen supports alpha channels!" << std::endl; _SUPPORTS_ALPHA = TRUE; } set_visual(visual);}/** * This simply adds a method which seems to be missing in Gtk::Widget, * so I had to use Gtk+ manually. * * Sets the visual for 'this' (the current widget). */void Transparent::set_visual(Glib::RefPtr<Gdk::Visual> visual) { gtk_widget_set_visual(GTK_WIDGET(gobj()), visual->gobj());}/** * If I click somewhere other than the button, this toggles * between having window decorations and not having them. */bool Transparent::on_window_clicked(GdkEventButton* event) { set_decorated(!get_decorated()); return false;}Hope this helps! 这篇关于如何在Linux上使gtkwindow背景透明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-18 12:05
查看更多