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

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.

Related

Is there a way to attach or anchor two QWidgets together?

I'm getting started with Qt and decided to build a full-screen text editor. I want to have a button (button with arrow in screenshot) attached to a QDockWidget which opens and closes it so the button is always visible to the right side of the screen and stay anchored to it when dock is visible or resized.
My current app is a simple fullscreen textEdit set to centeralwidget in Mainwindow.
I haven't found a way to do this yet with layouts or existing addAnchor() functions so any help or direction is appreciated.
You can achieve what you want by using a container for your text edit and the button. A QWidget instance can be used as an "invisible"*** container for other widgets.
So in Qt Designer you add a widget as a central widget of the main-window, inside this widget you add the text edit and the button, then you set a vertical layout for this container widget.
Don't forget to restrict the docking widget to only dock to the right side, you can do that with: dock->setAllowedAreas(Qt::DockWidgetArea::RightDockWidgetArea); //assuming dock is the pointer to your QDockWidget.
In case you want the dockWidget to be able to dock to any side and the button to follow, you can do that too, but it get a little bit more complicated. Basically you need to connect a slot to dockLocationChanged of your dockWidget and based on where it's docked you need to set-up a new layout for the container widget to be vertical or horizontal and the order of the textEdit and the button based on the side the dock happened.
LE:*** you will most likely need to set the margins you want, since both the widget and it's layout can have them and the actual content might have higher spacing than you want.

Add widget next to qscrollbar

How do I place a widget next to a QScrollbar like here seen:
I use a QScrollArea and overwrite the Horizontal-QScrollBar. First I thought, I could use the paintEvent to draw a text like the "100 %" next to the bar. But I can only overwrite the existing painting.
Now I think, the only opportunity would be to implement the hole QScorllBarPrivate from the source code... anyone any idea?
The main idea is to create an overlay obscuring default horizontal scroll bar and displaing your own bottom line instead.
Create a widget representing the bottom line, i.e. a widget with labels displaying some information and a horizontal QScrollBar, all together put in a hbox layout.
Put this widget in the scroll area without adding it to a layout by making QScrollArea direct parent widget of this widget.
Use move() and resize() on the bottom line widget to position it properly on initialization. Also resize and reposition it on scroll area resize (you can use event filters or inheritance to get to resize events).
Make sure that scroll area's horizontalScrollBarPolicy is Qt::ScrollBarAlwaysOn so that scroll area's internal layout always keeps space enough for bottom line widget to fit in.
Also make sure that bottom line widget has the same height as default scroll bar. It should be easy as long as you remove spacing and margins in the hbox layout and labels (or other widgets) don't require more vertical space than a scroll bar.
Use horizontalScrollBar() to get scroll area's internal QScrollBar and syncronize it with your own bar. QScrollBar has rangeChanged() and valueChanged() signals so you can connect to them and update your bar properly. When user changes value of your scroll bar and triggers its valueChanged() signal, you should set the same value for the internal scrollbar. You can protect from infinite recursion in there by using a flag that indicates that this is your own change.

A scrollbar event when scrolling?

I need an event for detecting if an user has moved the scrollbar position to another one.
In other words, if the user does scroll up/down, would it be possible to catch a signal so I can know the scroll has been changed its position?
I think it's not important, but the scrollbar I refer to is inside a QGraphicsView.
Regards.
Edit:
QGraphicsView is for displaying items in the screen, and if those items are too big it shows the scrollbars I refer to. What I need is to know when the user changes the position of those scrollbars.
Sliders have a sliderMoved(int value) signal, where value is the new position of slider.
If you need to get notified when the scroll bar position is changed, you need to subclass the QGraphicsView and reimplement the QWidget::mouseMoveEvent(QMouseEvent*). For this you also need to enable mouse tracking. Here is Qt 4.7 QGraphicsView reference.

Qt - QGraphicsView without ScrollBar

I am trying to show a picture in it's full view using QGraphicsScene. But when ever I put the QgraphicsScene inside the QGraphicsView, I am getting a scroll bar. I tried so many ways But all are went to veins. So can anybody tell me how to obtain the full view without the scrollbar.
You might be getting scrollbars because the scene is larger than the usable area within the graphics view. By default, a QGraphicsView comes with a 1-pixel margin. To fix this, you can try:
QRect rcontent = graphicsView.contentsRect();
graphicsView.setSceneRect(0, 0, rcontent.width(), rcontent.height());
I had been getting scrollbars because I was manually setting the scene rect to the size of the graphics item I was adding -- which was as large as the QGraphicsView widget. I wasn't taking into account the margin.
QGraphicsView v;
v.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
v.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
To adjust the scrolling programmatically once these have been hidden, use one of the overloads of v.ensureVisible().

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?