简体   繁体   中英

How to have a transparent widget in a non transparent window?

I am currently creating a terminal emulator in C++ with libgtkmm and libvte.

My purpose is to have a tranparent terminal widget and an opaque window elsewhere ; but I could not find anything about widget transparency.

I tried

GdkRGBA background = {0., 0., 0., .5};
vte_terminal_set_color_background(VTE_TERMINAL(terminal), &background);

and / or

set_opacity(.5); // set opacity of the container

for example, but it does not work. I guess it is a trick to do with the Gdk surfaces, but I cannot figure what.

I am looking for explanations, documentation, clues, etc...

Thank you !

EDIT :

I want to see the desktop below the widget (as if there were an opacity of 0 in the window). But if I modify the opacity of the window :

this->set_opacity(0.5);

the whole window is modified, not just the zone of the widget...

I want it looks like this :

这是一个例子

I am too used to doing everything through Glade. So i will start with that. I had no problem making any widget transparent with 'opacity' property:

   <object class='GtkWhatever' id='Whatever'>
     <property name="opacity">0.29999999999999999</property>
     <child>
       ...
     </child>
     <child>
       ...
     </child>
   </object>

This way all the children become transparent, which makes sense.

I then tried playing with set_opacity , and the most probable cause of your error is that you have called it exactly as you wrote, which would of course, set opacity of the object you call it from, and most often it is the application window.

You need to call it on the object that you want to become transparent (and all of its children will become transparent as the result).

So you have:

class MyWindow : public Gtk::ApplicationWindow
{
  private Gtk::Widget *someWidget;
};

Let us assume that you create this someWidget just fine and add it to the window. You can then do:

 someWidget->set_opacity(0.5);

It worked here when i tried it, so it should work for you as well. If not, please provide more detail, i will try to help.


After your comment i see that i have misunderstood what you wanted somewhat.

Opacity doesn't really work in the way that you want it to. You cannot lower the parent's opacity in the child, you control only opacity of it, and of all the children of if.

So let's say you have:

  • Gtk::ApplicationWindow *window
    • Gtk::Box *box
      • Gtk::Menu *menu
      • Gtk::Grid *grid
        • Gtk::Widget *w1
        • Gtk::Widget *w2
        • Gtk::Widget *w3
        • Gtk::Widget *w4
      • Gtk::Button *button

The way w3 will be displayed can be seen as:

  1. Draw *w3 onto *grid with the opacity of *w3
  2. Draw *grid onto *box with the opacity of *grid
  3. Draw *box onto *window with the opacity of *box
  4. Draw *window onto the screen with the opacity of *window

Keep in mind that the call sequence of drawing function is actually the opposite of this, the parent is responsible for drawing the child.

Therefore the opacity of each object also influences how its children look in the final output. If you window->set_opacity(1.0); , then nothing that you will do in children will let you see the wallpaper, since the window is already in the way. But if you window->set_opacity(0.0) to make it transparent, then you will not see any children at all, since they are not drawn on screen directly, but have to go through the parent.

As far as i know there is no way to break out of this hierarchy from the perspective of the child. I can see some very theoretical possibility that you can cut into the window drawing, perhaps by supplying your own function, and then somehow not draw some of own pixels at all, but take what draw function of child does and place it there as is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM