Alternative to QGraphicsDropShadowEffect for Frameless Window Shadow [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Like many software applications today, I want my program to have a frameless window that still has a drop shadow to make it fit better with the OS. The first step was to set the window flags to Qt::FramelessWindowHint to remove the frame. But the trickier part is adding a drop shadow to the outside of the window. I opted to add a QGraphicsDropShadowEffect to a smaller base widget that holds everything and make QMainWindow transparent by setting the attribute Qt::WA_TranslucentBackground to true.
This seems to be a good solution for me, until I added a QSizeGrip to enable resizing of the window. Every time the window gets resized, a paint event is called and the QGraphicsDropShadowEffect needs to be recalculated. This results in SUPER choppy resizing and a big performance hit.
Are there any alternatives to QGraphicsDropShadowEffect that has better performance?

I came up with my own solution that I haven't seen on SO yet.
I ended up making 12 png images that when arranged in a set of layouts, gives the illusion of a drop shadow. I'm sure there are many ways to do this, but what I did was split each side into 3 parts. This accounts for many different ways the drop shadow could be set up (offset and corner rounding)
Here's an exaggerated diagram:
The red areas are QLabel's with pixmap icons aligned to the outer corners. The purple areas are QLabel's with repeating background images. The red areas sizes are fixed but the purple areas can expand freely as set via min/max sizes and layout stretching. The top and bottom edges are horizontal layouts and the left and right edges are vertical layouts.
This works very well for my use case and solved all the choppy problems :)

Related

Qt: how can I make QWidget show up in more than one location on my mainWindow? [duplicate]

This question already has answers here:
Use the same widget in two different layouts in Qt
(3 answers)
Closed 6 years ago.
I have a QMainWindow with a large number of graphs (I am using QCustomPlot for those). As a result, each graph is inevitably rather small in size. All the graphs in this page are drawn on the 1st page of a QStackedWidget.
To provide a clearer view for each graph (one at a time), I want to show a larger view of a graph when the user clicks on one.
A potential solution is to have a 2nd page on the QStackedWidget in which the larger graph can be shown. The question is how do I go about assigning the selected graph to the 2nd page of a QStackedWidget?
Alternatively, is there a better way to enlarge a specific QWidget so that it occupies the mainwindow from end to end?
How can I let the 2nd page of the QStackedWidget update its contents directly from the selected graph?
Is there an example I could see to understand what I should do?
In addition to the linked question, at this point you may be focusing on premature micro-optimizations. The smaller graph will be rendered on a much lower resolution, so it wouldn't look too good if you blow it up.
If it was your own custom widget with some complex drawing, you could easily draw onto a pixmap, then draw the big pixmap onto the big graph, and downscale it for the small graph. But then again, you'd be doing a whole lot of extra drawing for all those small graphs on the odd chance they get to the center position. You can optimize that, but will increase complexity.
It would still be possible to do it for QCustomPlot, but it won't be that easy, and I doubt the effort to do it will see worthy returns. So just create an extra big graph when you need it and don't worry about performance before you run into problems with it. The difference will be negligible, as graphs aren't too complex to draw. You won't be updating one graph from another, you will simply be using the same data set in two graphs.

Simple OpenGL GUI Framework User Interaction Advice? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm designing a simple GUI framework from scratch as a project, using OpenGL and nothing else external and need some advice on how I might implement user interaction.
Basically, I've a base class GUIItem from which all elements inherit. This gives each item some basic variables such as position, a vector to contain child elements as well as some basic functions for mouse movement and clicking.
All elements are setup as above, with their relevant member variables.
What I'm struggling with is how to implement user interaction properly. In my window manager I would create a new instance of an item, say GUIButton and call it button1. The window manager would, upon a click occurring, iterate through its list of elements and any child elements they may have, calculating a rectangular area around the object based on its coordinates, height and width, then running any "on click" function associated with said item, like change the value of textlabel1.
Firstly, is there a better way to do this calculation? It would work for rectangular elements but spherical objects and others would have a much larger erroneous area which could be clicked. Ideally I would check pixels but I've no real idea how that would be achieved. I've heard about but never used GLUT (my project only allows use of this for handling mouse/keyboard interaction though). Does GLUT provide anything to assist in this case?
My main issue is with handling what would occur when an "On click" event actually occurred. At the moment GUIButton for example, has an "On click" function built in, so as far as I can see, I'd have to do something like make it a virtual function, meaning that each new button I created would have to have its own class just to overwrite the "on click" function and each instance of a button would be an instance of a unique class that simply inherited off of GUIButton. This seems messy to me, as I've no idea where I would store all those classes, and it seems a lot of extra code. Would I be creating a button1.cpp and button1.h file?
Any advice on this really would be welcome as I'm new to C++, OpenGL and it's the first time I've been exposed to GUI programming and there's not a lot to go on when an existing GUI framework is the usual choice.
if you want something stupidly simple and fast then you could:
create shadow screen buffer containing ID/index/pointer instead of color
pre-render this buffer
Just render each of your visual component to it but instead coloring/texturing just fill in the ID/index/pointer of rendered component. Do not forget to clear this with some NULL first ... After this you should have mask of your components. You need to do this just once ...
On mouse events
you simply convert mouse coordinates to the shadow screen space and pick the value. If it is NULL then you clicked or whatever on empty area. If it contains ID instead update or call the callbacks for component ID. if you have a list of all components then ID can be the list index, otherwise use its actual pointer or encode in style (component_type, component_index). As you can see this is pretty fast O(1) item selection no matter how many components you have ... The shadow screen can have different resolution then your actual screen (to preserve memory).
This have pixel perfect mouse selection accuracy no matter the shape of your components without the need for nested component search loops.
[Notes]
As I did this stuff here are some hints:
create a window class containing configuration of your components for single screen. Programs have usually more screens with different set of components and doing dynamically the screens over and over again just because you switch page/screen sucks.
use separate list of components one list per component type.
create IDE editor for your windows see drag & drop example in C++ it might get handy for this. Add get,set functions controlled by string/enum or flag to easy obtain/change properties to make Object Inspector possible. Also this is how mine IDE looks like:
The window is saved from IDE directly as C++ code I can just copy to my App. This is the above example without the knob (forgot to save it):
//---------------------------------------------------------------------------
// OpenGL VCL window beg: win
win.grid.allocate(0);
win.grid.num=0;
win.scale.allocate(0);
win.scale.num=0;
win.button.allocate(0);
win.button.num=0;
win.knob.allocate(0);
win.knob.num=0;
win.scrollbar.allocate(3);
win.scrollbar.num=3;
win.scrollbar[0].x0=200.0;
win.scrollbar[0].y0=19.0;
win.scrollbar[0].xs=256.0;
win.scrollbar[0].ys=16.0;
win.scrollbar[0].fxs=8.0;
win.scrollbar[0].fys=19.0;
win.scrollbar[0].name="_vcl_scrollbar0";
win.scrollbar[0].hint="";
win.scrollbar[0].min=0.000;
win.scrollbar[0].max=1.000;
win.scrollbar[0].pos=0.000;
win.scrollbar[0].dpos=0.100;
win.scrollbar[0].horizontal=1;
win.scrollbar[0].style=0;
win.scrollbar[0].resize();
win.scrollbar[1].x0=200.0;
win.scrollbar[1].y0=45.0;
win.scrollbar[1].xs=256.0;
win.scrollbar[1].ys=16.0;
win.scrollbar[1].fxs=8.0;
win.scrollbar[1].fys=19.0;
win.scrollbar[1].name="_vcl_scrollbar1";
win.scrollbar[1].hint="";
win.scrollbar[1].min=0.000;
win.scrollbar[1].max=1.000;
win.scrollbar[1].pos=0.000;
win.scrollbar[1].dpos=0.100;
win.scrollbar[1].horizontal=1;
win.scrollbar[1].style=0;
win.scrollbar[1].resize();
win.scrollbar[2].x0=200.0;
win.scrollbar[2].y0=70.0;
win.scrollbar[2].xs=256.0;
win.scrollbar[2].ys=16.0;
win.scrollbar[2].fxs=8.0;
win.scrollbar[2].fys=19.0;
win.scrollbar[2].name="_vcl_scrollbar2";
win.scrollbar[2].hint="";
win.scrollbar[2].min=0.000;
win.scrollbar[2].max=1.000;
win.scrollbar[2].pos=0.000;
win.scrollbar[2].dpos=0.100;
win.scrollbar[2].horizontal=1;
win.scrollbar[2].style=0;
win.scrollbar[2].resize();
win.interpbox.allocate(0);
win.interpbox.num=0;
win.dblist.allocate(0);
win.dblist.num=0;
// OpenGL VCL window end: win
//---------------------------------------------------------------------------
Look at images here plotting real time Data on Oscillocope for some ideas (I got this working for both GDI and OpenGL)
It is better to use pixel units instead of OpenGL <-1,+1> screen units for better visual quality and editing comfort.

RectangularGlow with Qt 4.7 without QML

I'm working on some Qt GUI application with shiny glossy design.
I have a list view customized with my QItemDeleagte subclass. I draw items in paint virtual method. Selected items need to be drawn with glow effect on the border. Normal items must be without glow effect
That's RectangularGlow QML Type which is exactly what I need my view items border to look like. Unfortunately the app was written in Qt 4.7 and there is no way to port the app and all its dependencies to Qt 5.
QGraphicsDropShadowEffect is not sutable since shadow gradient has one direction and an offset. QLinearGradient doesn't help too or I don't know how to use it.
I consider drawing some kind of border image.
Is there any proper and elegant way to implement this using gradients or graphics effects?
EDIT:
As cmannett85 pointed out QGraphicsDropShadowEffect seems to be ok. However graphics effect may be installed on a whole paintdevice and for view item i cant just draw only selected item border rectangle with glow effect and leave other elements in a normal state. Instead all drawing on a list view affected
EDIT2:
I found a solution in an answer for another question. So I think this question may be closed

Strange delayed painting with Qt5 on Windows

I'm using Qt5 in Windows. I just created a simple little widgets project in Qt Creator. I have a QMainWindow with a text edit widget inside. I enabled vertical layout, so the text edit consumes the full size of the inside of the main window (which is what I want, I'm trying to create a small notepad app).
As I drag the bottom right corner of the main window during the preview (I click the green triangle in the bottom left) I'm seeing a slight delay in the child widget's resizing. It doesn't exactly resize with the parent window on the same render frame (it seems like it is 1-2 render frames behind).
I remember years ago dealing with render lag like this in old school Win32 API. I remember I had to do double-buffered rendering into an offscreen bitmap to fix it (or something along those lines; been a long time).
Is there a way to fix this "render lag" in Qt? I can only imagine this is specific to Windows and might not impact other platforms, although I have not tested. If I need to provide more information let me know.
It is likely a Windows problem, not Qt's. The more GUI-heavy your window is the more noticeable it is.
I investigated the same issue a while ago. We had a rather GUI-heavy window, with several widgets displaying 2D and 3D views of data. Resizing the window using lower-right corner resulted in a resize-redraw horror. Unfortunately it looks like the problem is not Qt related but rather the way that Windows handles redrawing a resized window. I was able to notice the problem even in the file explorer on Windows 7. Qt is indeed using double buffering by default (as mentioned in the comment by #Bim). I also tried explicitly triggering Qt's repaint events. This helped a little, but did not solve the problem. So after many efforts we just decided to live with it.

See if mouse click was handled

I'm currently making a whimsical iPhone app that will allow you to change your windows cursor into a space ship controlled by the iPhone (simple rotation and such), and currently I have the movement and clicking handled, however I'd like to add additional features, such as bullets that you can shoot around the screen which will move until they die or hit a button, which will then be clicked. And I have two questions:
Question number one: Is there any way to detect if the mouse is currently over some click-able button? OR is there any way to see if a mouse event was handled?
Question number two: Is there any way to overlay the screen with small bullets? (perhaps small [3,3] child windows or something?)
Further Information:
The client program will be in c++
SDL or SFML will likely be the graphics libs, if any are necessary (winAPI should be fine)
The most reliable route would be the Microsoft Active Accessibility interface. Many tools to help visually impaired people need to answer the question "Is this a button?", and MSAA answers that question.
Overlaying the screen is trvial in a Windows environment; just create a window :). It can be partially transparent, so you're not restricted to rectangular bullets.