QPropertyAnimation for QGraphicsPolygonItem doesn't work - qt

I have a class which is derived from QGraphicsPolygonItem. Inside there is a function which is responsible for animation. The function looks like:
void DrawBase::makeAnimation(){
/* creating 2 states */
QState* st1 = new QState();
QState* st2 = new QState();
st1->addTransition(this, SIGNAL(clicked()), st2);
st2->addTransition(this, SIGNAL(clicked()), st1);
/* adding states to state machine */
_stateMachine.addState(st1);
_stateMachine.addState(st2);
_stateMachine.setInitialState(st1);
QObject::connect(st1, SIGNAL(entered()), this, SLOT(animate1()));
QObject::connect(st2, SIGNAL(entered()), this, SLOT(animate2()));
/* starting machine */
_stateMachine.start();
}
Connected slots animate1() and animate2() look like:
void DrawBase::animate1()
{
qDebug() << "Animation 1";
animation = new QPropertyAnimation(this, "polygon");
animation->setDuration(1000);
animation->setStartValue(this->polygon());
QTransform trans;
trans=trans.scale(0.5,0.5);
QPolygonF newPoly=trans.map(this->polygon());
animation->setEndValue(newPoly);
animation->setEasingCurve(QEasingCurve::OutBounce);
animation->start();
}
Polygon property was not seen by QPropertyAnimation, so I defined the property in the header like:
Q_PROPERTY (QPolygonF polygon READ polygonNew WRITE setPolygonNew)
PolygonNew and setPolygonNew call polygon() and setPolygon() of QGraphicsPolygonItem class.
As result animation is started but not working and I am not sure if it should work for polygon items at all. In the beginning of the animation polygonNew is called three times, setPolygonNew is not called at all. Does anybody have ideas about how I can make it work?

QPolygonF is not a supported type for QPropertyAimation. You can see the supported types here.
You have to provide your own interpolation function to make it work with QPolygonF.
Here is an example provided by the Qt docs:
QVariant myColorInterpolator(const QColor &start, const QColor &end, qreal progress)
{
...
return QColor(...);
}
...
qRegisterAnimationInterpolator<QColor>(myColorInterpolator);
Here is how to do it with QPolygonF:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
Q_PROPERTY(QPolygonF polygon READ getPolygon WRITE setPolygon)
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void setPolygon(QPolygonF polygon);
QPolygonF getPolygon() const;
private:
Ui::MainWindow *ui;
QPolygonF poly;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPropertyAnimation>
QVariant myPolygonInterpolator(const QPolygonF &start, const QPolygonF &end, qreal progress)
{
if(progress < 1.0)
return start;
else
return end;
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
qRegisterAnimationInterpolator<QPolygonF>(myPolygonInterpolator);
poly << QPoint(10,0);
QPropertyAnimation *animation = new QPropertyAnimation(this, "polygon");
animation->setDuration(1000);
QPolygonF start;
start << QPoint(0, 0);
animation->setStartValue(start);
QPolygonF end;
end << QPoint(100, 100);
animation->setEndValue(end);
animation->start(QAbstractAnimation::DeleteWhenStopped);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setPolygon(QPolygonF polygon)
{
poly = polygon;
}
QPolygonF MainWindow::getPolygon() const
{
return poly;
}

Related

Subclass of QGraphicsItem only receives hover event on the border from bounding rectangle

I'm developing with Qt-5.15.1. I want to customize QGraphicsItem, and in this customized item one rectangle and some surrounding circles added. The little circles will show when the mouse is hovering on that rectangle. So I reimplement the hoverEnterEvent and hoverLeaveEvent function to receive mouse hover event, please refer to minimal example.
Then, in paint event I can determine whether draw circles or not based on _mouseEnter.
Here comes the problem, I found the hoverEnterEvent will triggered as soon as mouse enter the border of that rectangle, however quickly hoverLeaveEvent is also triggered as mouse go through the border, being near the center of rectangle. Seems the border is the entity of mouse hover event, not the filled rectangle. So I can only show circles on when mouse is hovering on the border of that rectangle.
I don't know if I miss something? In my opinion, shape() and boundingRect() will affect these mouse events on when event happens? I want to make shape() to return a filled rectangle of QPainterPath, but don't know how to.
Update: minimal example
customizeitem.cpp
#include "customizeitem.h"
#include <QDebug>
CustomizeItem::CustomizeItem(QGraphicsItem *parent):
QGraphicsItem(parent),
_bbox(0,0,120, 120),_radius(7),
_mouseEnter(false)
{
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
setAcceptHoverEvents(true);
_rectRect = QRect(QPoint(_radius*4, _radius*4), QPoint(_bbox.width() - _radius*4, _bbox.height() - _radius*4));
QPointF upCenter(_bbox.width()/2, _radius);
QPointF rCenter(_bbox.width() - _radius, _bbox.height() / 2);
QPointF downCenter(_bbox.width()/2, _bbox.height() - _radius);
QPoint lCenter(_radius, _bbox.height() / 2);
_anchorRects.push_back(QRectF(upCenter, QSizeF(_radius, _radius)));
_anchorRects.push_back(QRectF(rCenter, QSizeF(_radius, _radius)));
_anchorRects.push_back(QRectF(downCenter, QSizeF(_radius, _radius)));
_anchorRects.push_back(QRectF(lCenter, QSizeF(_radius, _radius)));
}
void CustomizeItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
qInfo() << "mouse enter";
_mouseEnter = true;
update();
QGraphicsItem::hoverEnterEvent(event);
}
void CustomizeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
qInfo() << "mouse leave";
_mouseEnter = false;
update();
QGraphicsItem::hoverLeaveEvent(event);
}
QRectF CustomizeItem::boundingRect() const
{
return shape().boundingRect();
}
void CustomizeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
painter->setRenderHint(QPainter::Antialiasing);
drawAnchors(painter);
painter->fillRect(_rectRect, QColor(255, 0, 0));
}
QPainterPath CustomizeItem::shape() const
{
QPainterPath path;
path.moveTo(_bbox.topLeft());
path.addRect(_bbox);
QPainterPathStroker stroker;
stroker.setWidth(10);
return stroker.createStroke(path);
}
void CustomizeItem::drawAnchors(QPainter *painter)
{
if(_mouseEnter)
{
for(int i = 0; i < _anchorRects.size(); i++)
{
QPainterPath path;
path.moveTo(_anchorRects[0].center());
path.addEllipse(_anchorRects[i].center(), _radius, _radius);
painter->drawPath(path);
}
}
}
customizeitem.h
#ifndef CUSTOMIZEITEM_H
#define CUSTOMIZEITEM_H
#include <QGraphicsItem>
#include <QObject>
#include <QPainter>
class CustomizeItem : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
enum { Type = UserType + 1 };
explicit CustomizeItem(QGraphicsItem *parent = nullptr);
~CustomizeItem() = default;
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);
QPainterPath shape() const;
private:
void drawAnchors(QPainter *painter);
QRect _bbox;
float _radius; // radius for circle anchor
QVector<QRectF> _anchorRects;
QRect _rectRect;
bool _mouseEnter;
};
#endif // CUSTOMIZEITEM_H
maiwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "customizeitem.h"
#include <QGraphicsView>
#include <QVBoxLayout>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QVBoxLayout *layout = new QVBoxLayout(centralWidget());
layout->setContentsMargins(0,0,0,0);
QGraphicsView *view = new QGraphicsView(this);
view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QGraphicsScene *scene = new QGraphicsScene;
CustomizeItem *item = new CustomizeItem;
scene->addItem(item);
view->setScene(scene);
layout->addWidget(view);
}
MainWindow::~MainWindow()
{
delete ui;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
QPainterPathStroker generates a hollow region around the rectangle so as soon as that border passes it is already out of the shape. The solution is to join that edge with the inner region:
QPainterPath CustomizeItem::shape() const
{
QPainterPath path;
path.moveTo(_bbox.topLeft());
path.addRect(_bbox);
QPainterPathStroker stroker;
stroker.setWidth(10);
QPainterPath strokerPath = stroker.createStroke(path);
strokerPath.addPath(path); // join
return strokerPath;
}
Or just adjust the bounding box rectangle to accommodate the extra size.
QPainterPath CustomizeItem::shape() const
{
QPainterPath path;
path.addRect(_bbox.adjusted(-5, -5, 5, 5));
return path;
}
Since your "hit" shape is rectangular, you can probably just re-implement boundingRect(), since the default QGraphicsItem::shape() actually uses boundingRect() result (according to docs).
QRectF CustomizeItem::boundingRect() const
{
return QRectF(_bbox.adjusted(-5, -5, 5, 5));
}

Accessing a delegate's input value from the model

I'm using a custom QTableView with a custom QAbstractTableModel and a QItemDelegate. I'd need to access the contents of the delegate's editor while the user is editing it, and after several attempts, I couldn't find anything satisfying.
Indeed, I've tried several things.
First: trying to access the delegate's current input (created through createEditor) through a property defined in QItemDelegate but... it seems that none exists. That's why I tried to add a QWidget* editor property and setting it in the createEditor.
Unfortunately, QItemDelegate's createEditor is supposed to be const, which makes me unable to set my property there (and since I don't control what calls createEditor, I can't do it before or after).
I don't really know what to do here. Actually, I also needed to know when the user started (or stopped) editing the cell content, which I eventually achieved by creating two const signals (editingStarted and editingStopped). I could probably create a const editorOpened(QWidget*) signal but it just feels bad and ugly...
I can't believe nothing "official" exists to achieve what I'm trying to do, hence this question. If I have everything wrong from the beginning, I'd be glad to know. If you have any other ideas, please suggest.
EDIT: Here is a minimal working example
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include <QTableView>
#include "mytableview.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
auto tableView = new MyTableView(this);
setCentralWidget(tableView);
}
MainWindow::~MainWindow()
{
}
MyItemDelegate.h
#ifndef MYITEMDELEGATE_H
#define MYITEMDELEGATE_H
#include <QItemDelegate>
#include <QLineEdit>
#include <QStandardItemModel>
class MyItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
MyItemDelegate(QObject* parent);
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
virtual void onCloseEditor();
virtual ~MyItemDelegate() = default;
signals:
// Const signals trick
void editingStarted() const;
void editingFinished() const;
void editorOpened(const QWidget*) const;
};
#endif // MYITEMDELEGATE_H
MyItemDelegate.cpp
#include "myitemdelegate.h"
MyItemDelegate::MyItemDelegate(QObject* parent) : QItemDelegate(parent)
{
connect(this, &QItemDelegate::closeEditor, this, &MyItemDelegate::onCloseEditor);
}
QWidget* MyItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
auto lineEdit = new QLineEdit(parent);
emit editingStarted();
emit editorOpened(lineEdit);
return lineEdit;
}
void MyItemDelegate::onCloseEditor()
{
emit editingFinished();
}
MyTableView.h
#ifndef MYTABLEVIEW_H
#define MYTABLEVIEW_H
#include <QTableView>
#include <QDebug>
#include "myitemdelegate.h"
class MyTableView : public QTableView
{
Q_OBJECT
public:
explicit MyTableView(QWidget *parent = nullptr);
signals:
public slots:
};
#endif // MYTABLEVIEW_H
MyTableView.cpp
#include "mytableview.h"
MyTableView::MyTableView(QWidget *parent) : QTableView(parent)
{
MyItemDelegate* delegate = new MyItemDelegate(this);
QStandardItemModel* model = new QStandardItemModel(this);
setItemDelegate(delegate);
setModel(model);
QList<QList<QStandardItem*>> items;
for(int i = 0; i < 10; i++)
{
items << QList<QStandardItem*>();
for (int j = 'A'; j < 'E'; j++)
items[i] << new QStandardItem(QString("%1,%2").arg(i).arg(static_cast<char>(j)));
}
for (const auto& row : items)
model->appendRow(row);
connect(delegate, &MyItemDelegate::editingStarted, []() {
qDebug() << "Editing started";
});
connect(delegate, &MyItemDelegate::editingFinished, []() {
qDebug() << "Editing finished";
});
connect(delegate, &MyItemDelegate::editorOpened, [](const QWidget* editor) {
auto lineEdit = qobject_cast<const QLineEdit*>(editor);
connect(lineEdit, &QLineEdit::textChanged, [](const QString& text) {
qDebug() << text;
});
});
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
The following solution maybe fits your needs. I just defined a new signal inside the delegate and connected to it inside the class owning the delegate.
MyItemDelegate.h
#ifndef MYITEMDELEGATE_H
#define MYITEMDELEGATE_H
#include <QStyledItemDelegate>
class MyItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
MyItemDelegate(QObject* parent);
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
virtual ~MyItemDelegate() = default;
signals:
void valueChanged(const QString&);
};
#endif // MYITEMDELEGATE_H
MyItemDelegate.cpp
#include "myitemdelegate.h"
#include <QLineEdit>
MyItemDelegate::MyItemDelegate(QObject* parent) : QStyledItemDelegate(parent)
{
}
QWidget* MyItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
auto lineEdit = new QLineEdit(parent);
connect(lineEdit, &QLineEdit::textChanged, this, &MyItemDelegate::valueChanged);
return lineEdit;
}
MyTableView.cpp
#include "mytableview.h"
#include <QStandardItemModel>
MyTableView::MyTableView(QWidget *parent) : QTableView(parent)
{
MyItemDelegate* delegate = new MyItemDelegate(this);
QStandardItemModel* model = new QStandardItemModel(this);
setItemDelegate(delegate);
setModel(model);
QList<QList<QStandardItem*>> items;
for(int i = 0; i < 10; i++)
{
items << QList<QStandardItem*>();
for (int j = 'A'; j < 'E'; j++)
items[i] << new QStandardItem(QString("%1,%2").arg(i).arg(static_cast<char>(j)));
}
for (const auto& row : items)
model->appendRow(row);
connect(delegate, &MyItemDelegate::valueChanged, [](auto v) { qDebug() << v; });
}

Image not displaying using QPainter drawImage

I have an QFrame within a QWidget, in my application. When I try to draw a draw a image within the QFrame, the image is inserted only when coordinates are (0,0) and if they are something like (100,100) the image is not drawn. I created a new class for the frame and implemented paintEvent(QPaintEvent *p) in it. Is there any thing I am doing here ?
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QFrame>
#include <QPainter>
#include "frame.h"
class frame;
namespace Ui {
class Widget;
}
class Widget : public QFrame
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
frame * f;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QFrame(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
f = new frame(ui->frame);
f->show();
}
Widget::~Widget()
{
delete ui;
}
frame.h
#ifndef FRAME_H
#define FRAME_H
#include <QObject>
#include <QWidget>
#include <QPainter>
class frame : public QWidget
{
Q_OBJECT
public:
explicit frame(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *p);
signals:
public slots:
};
#endif // FRAME_H
frame.cpp
#include "frame.h"
frame::frame(QWidget *parent) : QWidget(parent)
{
}
void frame::paintEvent(QPaintEvent *p)
{
QPainter* pPainter = new QPainter(this);
QImage img(":/left.png");
Q_ASSERT(!img.isNull());
QRect source(0,0,20,10);
QRect target(50,50,20,10);
pPainter->drawImage(target, img,source);
QWidget::paintEvent(p);
QWidget::update();
}
If I use QRect target(0,0,20,10) in the above code the image is drawn.
testImage.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = testImage
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp\
widget.cpp \
frame.cpp
HEADERS += widget.h \
frame.h
FORMS += widget.ui
RESOURCES += \
src.qrc
DISTFILES +=
I am being stuck in this one for a long time, any idea will be helpful. I have tried Qt verions 5.6 and 5.8, similar result. And the OS is Lubuntu. The image resolution is 20*10. Thanks.enter image description here
Try like this:
void frame::paintEvent(QPaintEvent *p){
QPainter lPainter(this);
QPixmap lPixmap(":/left.png");
Q_ASSERT(!lPixmap.isNull());
QRect source(0,0,20,10);
QRect target(50,50,20,10);
lPainter->drawPixmap(target, lPixmap);
QWidget::paintEvent(p);}
remove update form painEvent and try to use pixmap.
I have found a solution, I have subclassed QgraphicsView and reimplemented paint method in it,
void graphicsView::paintEvent(QPaintEvent *e)
{
QGraphicsView::paintEvent(e);
QPainter pPainter(this->viewport());
QImage img(":/images/x.png");
Q_ASSERT(!img.isNull());
QRect target(300,230,20,10);
pPainter.drawImage(target, img);
}

Drawing a point in the exact position of a mouse click using Qt

I'm working on a Qt project. A point must be drawn on a mouse click on a Qpainter area. The point position is supposed to be on the same exact position of the mouse click, but for some reason the point is drawn in another position diagonal to the expected position.
The code :
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
QGraphicsView * view = new QGraphicsView(this) ;
ui->setupUi(this);
QGridLayout * gridLayout = new QGridLayout(ui->centralWidget);
gridLayout->addWidget(view);
scene = new QGraphicsScene();
scene->setSceneRect(50, 50, 350, 350);
view->setScene(scene);
}
void MainWindow::mousePressEvent(QMouseEvent * e)
{
QGraphicsView * view = new QGraphicsView(this) ;
double rad = 1;
QPointF pt = view->mapToScene(e->pos());
scene->addEllipse(pt.x()-rad, pt.y()-rad, rad*2.0, rad*2.0,QPen(), QBrush(Qt::SolidPattern));
}
Your code is not correct. You create heavy view every clicking, you should not do this. If you want that user will be able to interact with scene, then create new custom scene and do all hat you need in scene.
#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include <QGraphicsScene>
#include <QPoint>
#include <QMouseEvent>
class GraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit GraphicsScene(QObject *parent = 0);
~GraphicsScene();
signals:
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
public slots:
private:
};
#endif // GRAPHICSSCENE_H
cpp:
#include "graphicsscene.h"
#include <QDebug>
GraphicsScene::GraphicsScene(QObject *parent) :
QGraphicsScene(parent)
{
}
GraphicsScene::~GraphicsScene()
{
qDebug() << "deleted scene";
}
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if (mouseEvent->button() == Qt::LeftButton)
{
double rad = 1;
QPointF pt = mouseEvent->scenePos();
this->addEllipse(pt.x()-rad, pt.y()-rad, rad*2.0, rad*2.0,QPen(),
QBrush(Qt::SolidPattern));
}
QGraphicsScene::mousePressEvent(mouseEvent);
}
Usage, for example:
#include "graphicsscene.h"
//...
GraphicsScene *scene = new GraphicsScene(this);
someview->setScene(scene);

some error with mousepressevent()

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMouseEvent>
#include <QDebug>
#include "my_qlabel.h"
#include<QTimer>
int px;
int py;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
tmrTimer = new QTimer(this);
connect(tmrTimer,SIGNAL(timeout()),this,SLOT(showthepositionofmouse()));
tmrTimer->start(20);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showthepositionofmouse()
{
ui->plainTextEdit->appendPlainText(QString(" x , y = ")+QString::number(px)+QString::number(py));
}
void my_qlabel::mousePressEvent(QMouseEvent *event)
{
if (event->button()==Qt::RightButton){
px = event->x();
py = event->y();
}
}
i Want to display the position of Mouse clicked
i use ui->plainTextEdit->appendPlainText(QString(" x , y = ")+QString::number(px)+QString::number(py)); to display this position. although i click mouse,it only show x,y = 0 0. why that?
The py and px that are accessed in my_qlabel::mousePressEvent, are member variables of my_qlabel and are not visible to MainWindow::showthepositionofmouse.
If you want them to be visible you should send them using a signal and slot.
http://qt-project.org/doc/qt-4.8/signalsandslots.html
Here is a way to implement it:
In my_qlabel.h have something like this:
class my_qlabel : public QLabel
{
Q_OBJECT
signals:
void right_click_xy(int x, int y);
// ...constructor and other functions
public slots:
void mousePressEvent(QMouseEvent *event)
{
int px, py;
if (event->button()==Qt::RightButton){
px = event->x();
py = event->y();
emit right_click_xy(px, py);
}
}
}
In mainwindow.h have something like this:
class MainWindow : public QMainWindow
{
Q_OBJECT
// ... constructor and other functions
public slots:
void on_display_click_xy(int px, int py)
{
qDebug() << "Received xy over signal slot:" << px << py;
ui->plainTextEdit->appendPlainText(QString(" x , y = ")+QString::number(px)+QString::number(py));
}
}
And inside your MainWindow constructor put the following:
QObject::connect(ui->my_qlabel_instance, SIGNAL(right_click_xy(int,int)),
this, SLOT(on_display_click_xy(int, int)));
Another alternate way of doing this, but is isn't as kosher, would be to drill down into your ui object and access px and py that way.
qDebug() << ui->my_qlabel_instance->py;
But this is not as elegant, and isn't signaled the same way.
Another idea to look into is to use a QPoint object instead of two ints.
Hope that helps.
The whole idea is bad, you must process this event within my_qlabel class via signals and slots, not outside of it. I would suggest something like this (emit signal with coordinates of mouse click):
Header my_qlabel.h:
#ifndef MY_QLABEL_H
#define MY_QLABEL_H
#include <QLabel>
#include <QPoint>
#include <QEvent>
class my_qlabel : public QLabel
{
Q_OBJECT
public:
my_qlabel( const QString & text="", QWidget * parent = 0 );
signals:
void clicked(QPoint pos);
protected:
void mouseReleaseEvent ( QMouseEvent * event );
};
#endif // MY_QLABEL
Source my_qlabel.cpp:
#include "my_qlabel.h"
#include <QMouseEvent>
my_qlabel::my_qlabel( const QString & text, QWidget * parent )
:QLabel(parent)
{
setText(text);
}
void my_qlabel::mouseReleaseEvent ( QMouseEvent * event )
{
emit clicked(event->pos());
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "my_qlabel.h"
#include <QtGui/QWidget>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void showthepositionofmouse(QPoint pos);
};
#endif // MAINWINDOW_H
and mainwindow.cpp:
#include "mainwindow.h"
#include <QDebug>
#include <QPoint>
#include <QHBoxLayout>
MainWindow::MainWindow(QWidget *parent) :
QWidget(parent)
{
my_qlabel* label=new my_qlabel("Text of my label",this);
label->setAlignment(Qt::AlignCenter);
QGridLayout *lay=new QGridLayout(this);
this->setLayout(lay);
lay->addWidget(label,0,0,1,1);
connect(label,SIGNAL(clicked(QPoint)),this,SLOT(showthepositionofmouse(QPoint)));
}
MainWindow::~MainWindow()
{
}
void MainWindow::showthepositionofmouse(QPoint pos)
{
qDebug()<< "Clicked, position="<<pos;
}

Resources