Detect widget change in QStackedWidget - c++

I have a GUI that is to be put on a screen that has hardware buttons which map onto function keys. When a top row key is pressed the idea is that the screen will change to a different view of the data with the side buttons mapping into the view currently displayed and displaying corresponding information on screen (button, or label).
I have a top-level widget that contains these buttons and a stacked widget with the different data view (widgets) inside. I can navigate within the stacked widget from the QMainWindow but I cannot work out how the widget knows it no longer has focus so I can pause updates to the data, and given one of these views is video data I don't want it to be constantly updating in the background. Is it reasonable here for the MainWindow to just disconnect all signals, change the widget and then make new connections or is there a better Qt approach? I didn't necessarily want such tight coupling as the view itself knows what it should display on the buttons, not the main window.
I tried overriding focusInEvent(QFocusEvent* e) in the children of the stacked widget but it is never called.

Your QStackedWidget has a signal currentChanged(int index), this signal is fired everytime the current displayed widget on the QStackedLayout changes, can't you use this signal to toggle a flag on the widget displaying video to not to render it?
Whent he currentWidget is the video widget you can resume the rendering of the data( imaghe ) supplied to it, else you can simply discard the data given to it and save CPU cycles by not rendering it?
Am I missing something here?

Related

Qt: How do I stack widgets to do a transition between them, by fading one in and the other out?

Here's my end goal: I want to transition between two images. I want the original image to fade out, and at the same time, the new image to fade in.
I know I need to modify the opacity, and I found this great link for "How to make Qt widgets fade in or out": How to make Qt widgets fade in or fade out?
I also know I need to set the image for the QWidget, and I found out how to do that with the following code:
m_image1 = new QWidget();
m_image1->setStyleSheet("border-image: url(\"" + m_imagePath1 + "\") 0 0 0 0 strech strech; ");
Where I'm stuck is the layout. How do I lay a QWidget directly on top of another QWidget.
I did read about QStackedWidget, and it seems like it would be useful: https://doc.qt.io/qt-5/qstackedwidget.html . There's a method to set the current widget via setCurrentIndex(int). However, it doesn't seem to allow me to be transitioning out a widget and transitioning in a widget at the same time. It just either is one widget or the other widget. And from the class description, it says "a stack of widgets where only one widget is visible at a time."
A lot of the layouts I'm aware of, position items next to each other, not on top.
So, my question is how do I stack the widgets to do a transition between the widget contents, by fading them in/out?
Thank you.

Non-clickable QPushButton

I've been trying to make a Qt test app to put two different 'scenes' in, using one main widget which is the window which can hide and show the two other widgets which are the different scenes. In scene 1, there is a QPushButton, which is connected to a signal which is connected to showing scene 2. However, when I click the button, nothing happens. I tried running in debug mode, and the first slot isn't fired, AND the animation of pushing the button down isn't triggering. Is this something to do with the fact that the button is inside a widget inside a widget? I'll add the code if necessary.

How does a Qt custom widget notify ScrollArea parent about change of view

I'm writing an image viewer as a custom Qt widget (see: https://github.com/dov/Qviv) and I now got stuck on the question of how to make my widget notify a parent QScrollArea of changes in the view port, and thus to tell it to move the scrollbars. E.g. if the image viewer changes the zoom factor as the result of a keypress then the scrollbars need to change their page size.
One way of doing it would be to have the widget explicitly check if the parent is a QScrollArea and then make an explicit call to its methods to notify it on any changes.
Of course I also need to connect the changes of the ScrollArea to the internal view of the image, but that is a different question. And I need to cut the infinite recursion where the widget reports changes to the scrollbar that report changes to the widget etc.
Edit 20:15 Wednesday (GMT/UTC) trying to clarify to Vjo and myself what I need.
What I am trying to achieve is the equivalent of a Gtk widget that has been assigned a pair of GtkAdjustment's that are connected to a horizontal and vertical scrollbar. In my widget GtkImageViewer, that QvivImageViewer is based on, whenever I change the view due to some internal event (e.g. a keypress) I update the GtkAdjustment's. The scrollbars are connected to such changes and are update accordingly. GtkImageViewer also listens to the GtkAdjustment changes, and thus if the user scrolls the scrollbars, the GtkImageViewer is updated with this information and can change its view. My question is whether there is anything similar to GtkAdjustment in Qt that you can connect to for changes, and update in which case the update will be propagated to all the listeners?
Thus I don't expect the ScrollArea to be part of QvivImageViewer, but if the user has placed QvivImageViewer within a ScrollArea, I want bidirectional communication with it so that the scrollbars reflect the internal state of the widget.
The simplest is to send the QResizeEvent event from your widget object to the QScrollArea object.
I finally downloaded the Qt sources and investigated how QTextEdit does it. What I found is that QTextEdit inherits the QAbstractScrollArea on its own, and thus the scroll area and the scrollbars are part of the widget. This is different from Gtk, which uses a higher level of abstraction, through its GtkAdjustment's that are used to signal changes between the scrollbars and the widget. The Qt model is simpler and this is the way that I will implement it in my widget.
It's been a while, but I ran across this same issue.
You can inherit QAbstractScrollArea if you'd like, but QScrollArea will work as well.
Your custom inner widget (i.e. the one that you are scrolling), should do the following when its size changes:
void MyCustomControl::resize_me() {
// recompute internal data such that sizeHint() returns the new size
...
updateGeometry();
adjustSize();
}
QSize MyCustomControl::sizeHint() {
return ... ; // Return my internally computed size.
}
I was missing the adjustSize() call, and without it the QScrollArea will ignore size changes of the internal widget.

Displaying a popup widget in QT over application border

Let's say that I have an application frame, and I want to show a popup QCalendarWidget over on the right side of the frame. Normally, QT will clip the edges of the QCalendarWidget, cutting it in half and not displaying the rest, as it would be over the right side border.
Is there a way to work around this limitation without resorting to implementing a QDialog?
I want the widget to be visible outside the bounds of it's container.
If you'd show your Calendar, let's say, after a button click, as QDateTimeEditor does, it's contents will not be clipped, cause it do not belong to frame. It will be just a widget, that shows in a dialog manner. And maybe you should even place it in QDialog, that is modal and provides some convenience methods, rather then simple QWidget.
Btw, why don't you want to use QDatetimeEditor?

Qt: Dragging a widget to scroll the widget's parent QScrollArea?

I've got a long horizontal QLabel displaying a png (the image shows a signal/time graph). Under that, I've got a QTableWidget. Both of these are in a QScrollArea because I want them to stay vertically aligned (the cells in the table correspond with the signal seen directly above them). I'm trying to add a handler to the QLabel such that the user can use the picture itself to scroll the scrollarea, rather than having to use the scrollbar. Is there a tried-and-tested way to do this? Directly setting the scrollarea's sliderPosition inside the QLabel's dragMoveEvent doesn't seem smart, because when the scrollarea scrolls it also leads to another dragMoveEvent on the (moving) QLabel.
I would suggest wrapping the combination (including the scroll area) in their own widget, and overriding the dragMoveEvent() on that widget. The dragMoveEvent() shouldn't be triggered when you change the scroll position if you are doing it this way, I wouldn't think, although I haven't actually tested it.