I'm creating an application for capturing the screen or a part of it, and for that I need to select the part of the screen I want to capture.
The idea is to create a fullscreen semi-transparent window and draw thing on it so the user can see what he is doing. I have a working implementation where the selected area is dislayed as a wxPanel, but I want to rewrite it to paint everything to the main wxPanel manually.
frame = new wxFrame(NULL, -1, "", wxPoint(0,0), wxSize(0,0), wxSTAY_ON_TOP|wxFRAME_NO_TASKBAR|wxFRAME_SHAPED);
panel = new wxPanel(frame, -1);
SetTopWindow( frame );
panel->Bind(wxEVT_KEY_DOWN, &wxMiniApp::OnKeyDown, this);
panel->Bind(wxEVT_KEY_UP, &wxMiniApp::OnKeyUp, this);
panel->Bind(wxEVT_LEFT_DOWN, &wxMiniApp::OnMouseStart, this);
panel->Bind(wxEVT_LEFT_UP, &wxMiniApp::OnMouseEnd, this);
panel->Bind(wxEVT_MOTION, &wxMiniApp::OnMouseMove, this);
panel->Bind(wxEVT_PAINT, &wxMiniApp::OnPaintPanel, this);
panel->SetFocus();
panel->SetBackgroundColour(wxColor(0,0,0,100));
panel->SetBackgroundStyle(wxBG_STYLE_PAINT);
frame->SetBackgroundColour(wxColor(0,0,0,0));
frame->Show();
frame->ShowFullScreen(true);
I use panel to capture the mouse/keyboard events and I want to do the painting there too, but I don't know how to do this.
I want to have semi-transparent black background and the selected area should be transparent white or even fully transparent (without the black background).
The result of every attempt was that either it draw a solid color background or I got the famous WinXP lag effect.
Can you give me a basic OnPaintPanel(wxPaintEvent &event) implementation using x, y, with, height of the selected area (can be in wxPython too, if you're more comfortable with it) ?
You need to use SetTransparent(), wxDC doesn't support using alpha transparency anyhow (wxGraphicsContext does but it wouldn't help here).
Related
Working with widgets, c++ and Linux
need something kind of:
this
but no borders and custom title.
Search for a few days, but nothing.
For now, there is a widget with setWindowFlags(Qt::FramelessWindowHint); and a peace of qss for semitransparent background. How can I blur it? Is is possible at all?
I do not think this can be done with Qt. Blurring can be done using https://doc.qt.io/qt-5/qgraphicsblureffect.html but it is only limited to the widgets painted by Qt. Which the underlying background is not, even if you manage to make your widgets transparent or semitransparent. Painting the background is always the business of the operating system (or window manager) and not the business of your application Qt.
You can certainly try to do some extreme hacking like grabbing the active screen before your window is displayed (see How to capture the current screen image using Qt?) then getting certain rectangle content of the image, which corresponds to the background of your window, then paint it blurred to the background of your application and then update it everytime you move or resize your window... But anyway, even if you manage this, this background will be static and not dynamic.
I recommend that you abandon the idea of blurry background and leave this function to the window manager and the operating system.
I have a widget as on overlay for another widget. The transparency works fine, as long as I don't clear the background of the overlay.
But I have to clear the widget to acutalize the displayed "effects". I tried to solve the inital problem (the background getting the default color) like described in 20848594, but except changing the color to black it had no effect...
Has anyone an idea why the widget which should be transparent does not display the underlaying widget(s)?
Here the code:
SudokuMarkerOverlayWidget::SudokuMarkerOverlayWidget(QWidget* parent, uint const fieldSize) : QWidget(parent)
{
// Translucent should be the correct one
setAttribute(Qt::WA_TranslucentBackground);
//setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TransparentForMouseEvents);
...
}
void SudokuMarkerOverlayWidget::paintEvent(QPaintEvent*)
{
QPainter painter(this);
painter.setRenderHint( QPainter::Antialiasing );
// Tried this too, no difference
// painter.setCompositionMode(QPainter::CompositionMode_Source);
// painter.fillRect( this->rect(), Qt::transparent );
painter.setCompositionMode(QPainter::CompositionMode_Clear);
painter.eraseRect( this->rect() );
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
...
}
EDIT:
Just noticed, using CompositionMode Source instead of SourceOver for my semi-transparent painting (gradient seen in first image) also causes them to be a red-to-black-gradient instead of red-to-transparent.
That means every transparency except the inital by WA_TranslucentBackground or WA_NoSystemBackground isn't working.
Widgets in Qt can be either a 'native' or 'alien' type. In one case they're a separate operating system window. In some operating systems a transparent window isn't supported.
You might want to consider using QML if you're after fancy visual effects. That's what it was designed for.
The question is in bold at the end so please read this as a whole.
I have a QAbstractScrollArea widget that I manually and completely render in the OnPaint() event.
In its constructor I set
setAttribute( Qt::WA_OpaquePaintEvent, true );
setAttribute( Qt::WA_NoSystemBackground, true );
setStyleSheet( "QWidget { background-color: rgb(0,0,77); }" );
and the paint event looks like this:
void MyArea::paintEvent (QPaintEvent *event) {
QPainter view(viewport());
view.fillRect(rect(), backgroundBrush);
renderedPixmap = heavyAndSlowRenderingOnAPixmap();
view.drawPixmap(viewRect, renderedPixmap, pixmapRect);
}
as you can see there's a "slow" function involved to render stuff into a pixmap.
The problem is: when I resize the window, I can see for a moment a white flickering in the area not yet redrawn
I know I can't avoid the white region until the viewport has been redrawn, but I'd like to draw that white region with the background color immediately.
So here's the question: can I display a background color immediately before the heavy-pixmap rendering?
I can't seem to find a way to achieve this.. it seems all graphics operations are buffered and then immediately bit-blitted to the screen together. I'm using Windows 8.1 x64 and Qt5. Any way to immediately draw the background color and then proceed with the rest of the rendering?
The best solution would be to move the expensive rendering out of the paintEvent(), potentially into another thread. You'll want to cache the rendered pixmap anyway. Update that pixmap when really needed and then call update() to trigger a repaint.
I got a problem. There is panel1 which i want to use as my paiting window. And i also have 2 buttons. One should draw "fillRectangle" in the middle of panel and second one should draw "fillellipse" next to it. I dont have the problem with drawing itself
Color aColor = Color::FromArgb( 255, 0, 0 );
SolidBrush^ aBrush = gcnew SolidBrush(aColor);
Rectangle rect = Rectangle(x, y, 10, 10);
e->Graphics->FillEllipse(aBrush, rect);
But i want to know, how to make that pressing each button draws different shape inside panel. Do i need to put both, ellipse and rectangle in panel1_Paint and use flags like...
if(ellip == 1) FillEllipse;
if(recta == 1) FillRectangle
which are set using buttons? I hoped i can code drawing part inside button or function, and then somehow refer to that panel. Is it possible?
If you want the buttons to have their own painting routines, then they draw themselves and your panel is unnecessary, in terms of drawing anyway, they'll have their own canvas.
If you want a panel that draws shapes on itself dependant on some property, then yes you go down something like the route you suggested, though I'd be tempted by some sort of shape class even if it wasn't a control. Would make adding other shapes or more of a shape much easier.
You could have panel carry a collection of shapes that implement say IDraw which takes a Graphics reference, and then just iterate through them and call it with Panel1's graphics instance.
If it was me though particulary if I wanted enabled, visible, tab, click etc. I'd have a ShapedButton Control.
I want to display a fullscreen transparent image anytime there is an active menu button in cocos2d. How do I do that?
If you're looking to provide a popup dialog underlay, you can use CCLayerColor:
CCLayerColor* underlay = [CCLayerColor layerWithColor:ccc4(0, 0, 0, 127)];
[self addChild:underlay z:(something less than your button's z)];
If it has to be a specific image, initialize the image and do the second line above using your CCSprite.