Qt: the most efficient way of displaying real time plain text? - c++

What is the most efficient way of displaying real time plain text?
If I need to display large amount of changing text with high frequency.
What is the best solution?
I have tried QLabel, QPlaintextEdit and I also tried to rewrite a widget's paintEvent and do painting there. But they all do not work very well.
Due to the platform limitation, I cannot use QGLwidget or openGL support.
And the texts need to be grouped in related widgets where the user can perform some basic interaction(like selecting) with those widgets. The expected thing is something like this:
EDIT:
The data comes from many different vehicles' sensors, you could consider that I store the incoming data simply in several arrays. The method I have tried all resulted in a slow responding GUI thread.

Related

Qt Qml: Dynamic number of moving axis aligned bounding boxes

I am writing a video display software capable of displaying multiple video streams. For this I have a GridView holding VideoOutputs in QML connected to a QAbstractListModel derived class in c++ which provides instances of an object with a QAbstractVideoSurface Q_PROPERTY. It's working quite beautifully so far.
The video frames I am displaying come with metadata, however, containing data for axis aligned bounding boxes. I don't know beforehand how many boxes there are, the number could even change on a frame by frame basis, their position and size is also not set.
Ultimately, it should look something like this:
As I need to be able to display a few video streams at once, and preferably at 30+ fps, I need a fast method of drawing these boxes. Using QPainter on the QImage on which the QVideoFrame is based is rather slow so I was considering a few other approaches:
Using the QML object Rectangle in a Repeater with a c++ provided model (Was hoping to simply provide a QVariantList::fromVector() ): Could work, however I would need a lot of models which in turn I need to provide to QML with a model, and I would likely need to call begin/endResetModel every frame that the boxes change to cause QML to update - this is also very slow.
Using a Shader to draw the boxes: This is a rather difficult approach. I'm no stranger to shaders, but in Qt/Qml I don't know how to provide the shader with the information necessary.
Using OpenGL directly to draw the boxes: Again, I have no clue how to do this, but I think I could work it out if I googled.
My question: Which one, if any, of these approaches is the best? If none of these, which other approach could I use?
Thank you so much for taking the time to read my rather long question!

Managing layouts in Qt with "empty" widgets for displaying images

I am designing a GUI in Qt that has placeholders for a number of images (images will be set and updated at run time) along with some input fields (QLineEdits with QLabels grouped into QGroupBoxes). I am using a technique similar to the answer here:
How do I make an image resize to scale in Qt?
for the image display widgets. Some are a class that inherits from QWidget that can draw an aspect-scaled image, others are a class that inherits from QLabel that can do the same and also display text. These are custom C++ classes.
The problem I am having is with the layout and getting things spaced correctly. I am using Qt Designer to layout the GUI. Since the image widgets are "empty" they don't exert a lot of "force" on the other widgets and the other widgets tend to dominate even though I don't need the other widgets to be that big. The QLineEdits especially like to be as wide as they can be. I want to GUI to be adaptable for different sizes (to accommodate different screen resolutions) so I don't really want to set a lot of sizes manually if I can help it.
I do not have a lot of experience in Qt and managing layouts. What I know I have mostly learned from playing around with it. I have tried searching for similar situations without much success. I can't figure out the terms to use for my specific situation. Does anyone have any suggestions for what I can do to better control the layout? Alternatively, are there any good resources for learning how to manage Qt's layouts? The Qt documentation I have looked at is fairly basic. There are a lot of options, most of which I am unsure exactly how they should work, and the trial-and-error approach is getting to be too cumbersome for more complex layouts.
I am using Qt 4.8.
Sorry to be vague. This is a work project and I would rather not post exactly what I have. And coming up with a generic example will take time. I think my questions are generic enough that it shouldn't matter. If a more specific example is needed, I can try to throw something together.
Edit:
Here is what the layout looks like in Designer right now. The black boxes are redacted labels. The orange boxes are where images will go. The one in the top-left corner is a particular problem. I currently have the top and bottom halves on the left in a splitter in an effort to make things fit better. I think that may be making it worse.
http://i.stack.imgur.com/nRRg3.png (long-time reader, first-time poster :-/)
Making the "What I want it to look like" picture is going to take a bit longer. It may be easy to see what I don't like. The input fields need to be much smaller to make room for the images.
Edit2:
And here's something closer to what I would like. The upper-left and right-hand images are larger and actually visible. I might like the boxes in the lower-middle to be even bigger, but there's only so much room. If I can get the layout right, I'm hoping that will optimize the size of everything for a given window size.
http://i.stack.imgur.com/yvLvi.png

Qt scrolling a large image

I need to implement a simple sound editor with a specific signal processing function.
I want to display the sound information vertically as a large picture - 1024 x [large height].
So I'm looking for Qt's best way to implement low-cpu-consuming vertical scrolling similar to web-browsers scrolling.
You need to create a custom widget by overriding it's paintEvent().
Have a look at this self-explanatory example on how to create a following widget.
A normal QScrollArea will give you what you want 99% of the time. But you're wanting to create a bitmap of potentially massive size, and you want to store it in RAM - you will quickly run out of space.
You are probably going to need a need a system where you save the image to file, and use the scroll area's bounds to intelligently load it's contents from the file (and a certain size around it to make it smooth) - Qt does not provide this. This is hardly groundbreaking stuff, so a web search for "scrolling very large images" or something similar should give a smart result.
If your intention is to plot STFT data, then you can easily adopt one of the widgets in the QWT library:
http://qwt.sourceforge.net/
Anyway, take a look at it, it is a great source of inspiration and the code is available...

What makes a Qt widget and its layout behave properly (in regard to its size)?

I'm having all sorts of size problems with Qt. I am creating my own widgets and using different layouts (generally, I need my own to make them work properly without spending hours on the "powerful" default layouts... which don't lay things out as intended.)
Once I'm done with a widget and its layout though, it doesn't work right. The size is never getting set properly unless I call widget->resize(1, 1); which finally forces a "resize" and makes the widget look correct (i.e. recompute the geometry.) Even the updateGeometry() call has no effect.
This is a dreadful problem when the resize() needs to be called on the parent widget (yuck!) and from what I'm reading should not be necessary were the layouts properly programmed.
Is there a sample that works and is not several thousand of lines long, or does Qt require several thousand lines to make anything work perfectly, even the simplest widget?
What are the minimal functions to be called to make a widget & its layout work at once?
Thank you.
Alexis
P.S. I tried to implement the sizeHint(), minimumSize(), maximumSize(), others that I'm missing? I was hoping that would be enough. Obviously, I also implement the setGeometry() on the layout to resize the children appropriately.
--- addition 1
There is a sample image with a layout that clearly isn't available as is in Qt. The positioning, functions, and colors of the different keys is XML driven and works for any keyboard in the world.
(note, this sample doesn't show the Enter key displayed on two rows and wider below than at the top; more or less, not doable at all with the regular layouts; of course, it works with my version.)
--- clarification
I'm not too sure how to describe the problem better. I was thinking to write a test widget next to see how I can reproduce the problem and then post that and eventually fix it. 8-)
The default layout function that the internal Qt layouts make use of require a lot of coding. I would like to avoid having to copy/paste all of that because for maintenance, it makes it close to impossible.
--- today's findings
As I needed to tweak one of the widgets, I decided to add a VBoxLayout and make it work.
I actually found the problem... One of the widgets in my tree is a QScrollArea and that sizeHint() returns (-1, -1). Not exactly what I'd expect but... whatever you put inside that widget has better know how to compute its width and height or else... it fails.
Looking at the code closely, I could actually compute the width by using the widest width found. Once I used that, the widget would appear (and it actually resizes itself as things change in the list, kinda cool.)
This being said, my earlier comment about having a tree of widgets that auto-resize themselves stands. From the root up to the parents of the leaves in your tree, all of those widgets will need a valid layout. Once I added one in the top widget it resized itself and its children properly (well... in my case up to the QScrollArea, the rest required a bottom to top resizing. Funny how that works!)
--- ah! ha! moment (or: what you find reading the implementation code!)
Today I bumped in another problem which just needed the correct call... I just couldn't find anything worth it in the documentation.
All the objects have a layout now, but a certain parent would not resize properly. Plain simple.
I had a call to the parent as following:
// changes to the children are changing the geometry
parentWidget()->updateGeometry();
Yeah. The docs says that's what you have to do. Nothing happens at all with that call. No idea what it's supposed to do, I did not look at that function. It never did anything for me anyway.
So... I looked at the layout to try to understand how it would send the info up/down. I did not see much except for one interesting comment:
// will trigger resize
This is said of the SetFixedSize mode. To reach that function you need to make the layout for update. Ah! Yes... the layout, not the parent widget... let's try that instead:
parentWidget()->layout()->update();
And voila! It resizes correctly in all cases I have. Quite incredible that the widget updateGeometry() doesn't trigger the same effect...
Although it's possible to do what you want it sounds like the problems you are having are because you're using Qt in a way that it's not meant to be used. Why do you need separate widgets for each key represented on the keyboard?
I see two options, both of which are better in some way:
Use QGraphicsScene and QGraphicsView.
A single custom widget that uses custom drawing to display the keyboard (and likely uses hover for hints).
The first option is probably better. Your keys could then be represented by QGraphicsSimpleTextItem's or even a QGraphicsSvgItem. It also provides a number of standard layouts or you could choose to write your own layout. By default you can use the keyPressEvent or mouseReleaseEvent to respond to user interactions.
I'd highly recommend you take a look at the QGraphicsView examples to get an idea what you can do.
If you go the second route you'll need to record the different key locations so you can respond accordingly as the user moves the mouse around, clicks, etc.
This won't help you with your immediate issue but I wanted to show you a keyboard I made using standard layouts and buttons. It's not perfect and it still won't help you with an enter key that spans two rows but it's not bad. It's resizable too by resizing the window, although I'm not sure if that will be apparent from the images below as SO may be scaling them. (you can view the actual images by opening them in their own tab)
Anyway, this was done using only Qt Designer with no manual coding. It consists of a top level vertical layout with 5 horizontal layouts in it. The buttons are then inserted into one of the 5 horizontal layouts. The size of the keys can be controlled by setting the horizontal and vertical size policies to "ignored" for most of the buttons and then horizontal "minimum" for buttons that you want to be wider. Things can be tweaked by setting min and max size restrictions to buttons. When resized, the buttons will not maintain their relative proportions though, that would probably take some custom programming.
The styling in your example could be approximated pretty well using css style sheets and background images. Still not a minor effort but you should be able to get most of the way there without custom layouts and buttons.

How do I get resize handles in QT?

Is there a way to get a resize effect between two widgets? Like say I have two QTextEdit boxes next to eachother, I want to get a handle between them so I can move it back and forth. Sort of in the same way that the textarea I'm writing in now has a handle at the bottom for making it larger.
I'm using QT Creator and I can't seem to figure this out. I got something similar to what I want by using a QDockWidget, but that really doesn't seem like the purpose for which it was intended.
What you need is a QSplitter.