我想让背景透明,只有窗口小部件可见.
这是我的代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
我用gtk3.程序执行时,它只显示黑色.CSS(或rgba)函数不起作用.我尝试使用gtk_window_set_opacity(),但它也只显示黑色.如何修复代码?
Ath*_*lex 14
我按照评论建议的链接,但不幸的是它是为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`
Run Code Online (Sandbox Code Playgroud)
这是代码:
/**
* 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_save (cr);
if (supports_alpha)
{
cairo_set_source_rgba (cr, 0.5, 1.0, 0.50, 0.5); /* transparent */
}
else
{
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */
}
/* draw the background */
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
cairo_restore (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));
}
Run Code Online (Sandbox Code Playgroud)
我包含了一个非常类似的程序,这次是用gtkmmC++ 编写的.它可以使用以下命令编译:
g++ -otransparent main.cpp transparent.cpp `pkg-config gtkmm-3.0 --cflags --libs` -std=c++11
Run Code Online (Sandbox Code Playgroud)
请注意,我使用了新的C++ - 11标准中的一些功能,因此您需要一个支持它们的编译器.(如果你没有一个,你只需要更换auto关键词时,出现使用合适的类型,你可以从函数的定义搞清楚.)中有三个文件:main.cpp,transparent.h,和transparent.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);
}
Run Code Online (Sandbox Code Playgroud)
/**
* 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_ */
Run Code Online (Sandbox Code Playgroud)
/**
* 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;
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
在遇到相同问题时,我注意到如果在show_all 函数之后在顶级窗口上调用gtk_window_set_opacity(),那么整个窗口(部分)对我来说都是透明的。试试看:
gtk_widget_show_all ( window );
gtk_widget_set_opacity (GTK_WIDGET (window), 0.5);
Run Code Online (Sandbox Code Playgroud)
那对你也有用吗?
| 归档时间: |
|
| 查看次数: |
7769 次 |
| 最近记录: |