Dov Grobgeld
Dov Grobgeld

Reputation: 4983

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.

Upvotes: 1

Views: 914

Answers (3)

Max
Max

Reputation: 3445

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.

Upvotes: 1

Dov Grobgeld
Dov Grobgeld

Reputation: 4983

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.

Upvotes: 1

BЈовић
BЈовић

Reputation: 64303

The simplest is to send the QResizeEvent event from your widget object to the QScrollArea object.

Upvotes: 1

Related Questions