How to scroll QLabel? - qt

I am trying to implement Picture Zoom In/Out and Picture Scroll on Meego/Qt/QML.
I have written a class A which is inherited from QLabel.
A::A( "parent" )
{
setAlignment();
setGeometry();
setScaledContents();
}
Now I have a Controller class B. This class is responsible to handle the events from QML to the my Class A. In my controller class I have instantiate in the following way.
B :: B()
{
a = new A();
proxyWidget = new QGraphicsProxyWidget();
proxyWidget->setWidget(a);
}
Since this is a QML based application I am handling events from QML.
For Zoom I have used PinchArea. Whenever I am getting PinchUpdated event I am setting the setGeometryof the QLabel accordingly. I am zooming in and zooming out.
For scroll I have used MouseArea with onPositionChanged event. However I am unable to scroll the label event after calling the scroll API of the QLabel.
Can someone please tell me where am I doing wrong?

I assume you want to zoom using mouse scroll for instance.
I am not good at QML but you certainly should be handling wheel events in your class A. It is not clear for me if every Qt event has a QML equivalent, but you can always put C++ code. The function to implement is :
virtual void wheelEvent ( QWheelEvent * event );
You have the delta variable which can be useful to determine the speed of zoom (using delta absolute value) and whether it should grow or shrink (using sign of delta)

Related

How to expose a C++ visual element to QML

"I want to draw my visual item object that created in c++ in qml."
current state.
I wrote a subclass of QQuickFramebufferObject in C++.
and it renders something using its renderer. so I think that is visual item.
I register the subclass through qmlRegisterType() for using it in QML.
I instanciated the class object in QML and set area to draw something.
After the engine loads qml, I find the object which made in QML and put it into a pointer in C++.
so that I can add data with the pointer and that updates in QML.
It is working well. rendering data on proper area.
problem I got.
I am using StackView element for navigation, and when I move to other view and comeback.
It seems QML instances in prev view are re-created, so my connections with C++ be invalidated.
solution I thought
I am not sure, that is right way or not. Anyway I tried to instanciate the object in C++ not in QML.
and register it to QML through setContextProperty().
and set parent, render area for that property, but it is not working the object do not render anything.
code outline is below
// in C++
mCustomWidget = new CustomWidget;
engine->rootContext()->setContextProperty("custom_widget", mCustomWidget);
// in QML
Item { // CustomContainer
id: container
Component.onCompleted: custom_widget.parent = container
onXChanged: custom_widget.x = x
onYChanged: custom_widget.y = y
onWidthChanged: custom_widget.width = width
onHeightChanged: custom_widget.height = height
}
I expected C++ side has the object so it would be not deleted whether move to other view or not.
With the pointer in QML side which is context property name, I can see the rendered results if I set its parent and render area.
but, It is something wrong so not working.
Please, let me know the wrong points or other solution. I would be appreciated it. Thank you.

QHeaderView mouse tracking fails

I need to connect some simple filter functionality, to a mouse click on a QTreeView header item. Simple enough, I implemented a slot function that connects to:
QTreeView::header()->sectionClicked(int)
After setting
QTreeView::header()->setSectionsClickable(true)
,sectionClicked is emitted any time I click on a header that is highlighted by the default hover effect that any clickable header will produce.
The issue is, hovering over some areas in clickable headers will not be recognized. Hence, in these parts there is no highlight and I will not get any sectionClicked triggers. I traced it back further and derived my own class from QHeaderView and put some output into mouseMoveEvent.
class MyHeaderView : public QHeaderView
{
Q_OBJECT
public:
MyHeaderView(QWidget* parent = 0)
: QHeaderView(Qt::Horizontal, parent)
{
setMouseTracking(true);
}
protected:
virtual void mouseMoveEvent(QMouseEvent* event)
{
qDebug() << event->pos();
}
};
While leaving all QTreeView settings as they were, I set an instance of this class to be the header via
QTreeView::setHeader(QHeaderView*)
I could see, that in all areas were the hover effect failed, I did not get the debug output you can see in the overridden mouseMoveEvent.
As a result I am assuming, that the mouse tracking is not working correctly.
The overall application I am working on is quiet big, so I set up a stand alone example, for all of this. To my surprise, everything works as expected. I am clueless, how I should proceed with this. Can anyone think of reasons for the mouse tracking to fail in some parts of a widget? Could it be a frame rate issue tied to lack of performance? Are there settings on widgets that affect the overall mouse tracked area? Can parent widgets affect mouse tracking?
In my application I have a controller class that handles a lot of application logic connected to various signals the tree view emits. This class is not suppost to render any visualization. Hence, it would be the most reasonable choice to derive from QObject. After a while I noticed, that it was in fact derived from QWidget. Being a QWidget I am guessing it tries to render some sort of visual representation, which the overlays the tree view. That's why I don't get any mouse events in some parts of the header.
After changing the base class of my controller to QObject, everything works fine again.

Is a QGraphicsSceneEvent::widget() always a QGraphicsView?

According to the docs, QGraphicsSceneEvent::widget() returns a QWidget. Isn't the widget always going to be a QGraphicsView, though (or null)?
I would assume so, except then I don't understand why the devs wouldn't have just made it QGraphicsSceneEvent::view().
The reason I'm asking is that in my subclassed QGraphicsScene, I have overridden QGraphicsScene::mousePressEvent() and I want to know which view originated the event--I'm wondering if it's safe to static cast widget() to a QGraphicsView, or if it's conceivable that some other widget could have created the event.
As it turns out, QGraphicsSceneEvent::widget() returns the viewport widget, not the QGraphicsView. If you want the QGraphicsView, you would need to use: event->widget()->parent().
Documentation page you refered mentions the QGraphicsView as a target of events:
When a QGraphicsView receives Qt mouse, keyboard, and drag and drop
events (QMouseEvent, QKeyEvent, QDragEvent, etc.), it translates them
into instances of QGraphicsSceneEvent subclasses and forwards them to
the QGraphicsScene it displays. The scene then forwards the events to
the relevant items.
However, if you doubt that QGraphicsSceneEvent::widget() always returns QGraphicsView, or you relay that it should always be a QGraphicsView you can check that by using qobject_cast:
QGraphicsView *view = qobject_cast<QGraphicsView *>(event->widget();
if (view) {
// Handle the event
} else {
// This is something that I do not expect.
// ..
}

How to get the size of QGraphicsView that is in a layout?

I'm new to Qt programming and I am developing a drawing application. I have a class MyWidget which has a member QGraphicsView. MyWidget is a member of another class MainWidget (which has other widgets as well and all of them are in a layout).MainWidget is the central widget of my subclass of QMainWindow.
I have created functions to scale the view with the mouse wheel event and a function to drag the scene around.
The problem is - I want to set the Scene's size to be fixed, and to be 3 times the size of the view, but since the view is managed by a layout in order to take as much space as possible I can't get the view's size?
Any help appreciated.
the size property will give you the current size of your widget:
http://qt-project.org/doc/qt-4.8/qwidget.html#size-prop
Alternatively, you could subclass QGraphicsView and re-implement the resizeEvent:
http://qt-project.org/doc/qt-4.8/qwidget.html#resizeEvent
For a full example, have a look into:
http://qt-project.org/doc/qt-4.8/widgets-scribble.html
You can definitely get the view's size. There are two ways to go about it:
Attach an event filter object to your view: myView->installEventFilter(filterObject). The filterObject's eventFilter method will be invoked for all events reaching your view, including resize events.
Use a custom view class and reimplement resizeEvent. This method gets called each time the widget is resized. Do note that designer allows you to add custom classes without having to write plugins.

How to show pixel position and color from a QGraphicsPixmapItem

I'm developing a custom widget with QGraphicsScene/View and I have no prior experience with it.
The custom widget is an image viewer that needs to track mouse movement and send signal(s) to it's parent dialog / window. The signal(s) will be the position of the pixel under the mouse cursor and it's color (in RGB). A status bar will use that information.
I use a QGraphicsPixmapItem to display the image I load from a file in the scene.
Thanks.
First of all you have to implement the mouseMoveEvent in your custom item. In this function you can easily get the mouse position calling the pos function. You can get the rgb value if you transform the item's pixmap into image and call the pixel function. You should consider storing the QImage as member variable in order to avoid multiple transformations. Finally you have to emit a custom signal. Sample code follows:
void MyPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
QPointF mousePosition = event->pos();
QRgb rgbValue = pixmap().toImage().pixel(mousePosition.x(), mousePostion.y());
emit currentPositionRgbChanged(mousePosition, rgbValue);
}
Notice that QGraphicsItems do not inherit from QObject so by default signals/slots are not supported. You should inherit from QObject as well. This is what QGraphicsObject does. Last but not least I would advise you to enable mouse tracking on your QGraphicsView
I found the mouseMoveEvent approach to not work at all, at least not with Qt5.5. However, enabling hover events with setAcceptHoverEvents(true) on the item and reimplementing hoverMoveEvent(QGraphicsSceneHoverEvent * event) worked like a charm.
The Qt docs on mouseMoveEvent() provide the clue:
"If you do receive this event, you can be certain that this item also received a mouse press event"
http://doc.qt.io/qt-5.5/qgraphicsitem.html#mouseMoveEvent

Resources