PDA

View Full Version : subclass the QLabel



ready
25th March 2011, 07:33
I want to get the coordinate from Qlabel when I double click on...
how do I sub class the Qlabel in ui application
my code looks:
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

MainWindow::~MainWindow()
{
delete ui;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();


private:
Ui::MainWindow *ui;
};

szisziszilvi
25th March 2011, 08:12
is your question probably about promition if you google it? If I understand well, you want to give extra features to QLabel, than in the first step "promote to" is your friend, you may find more information in the documentation.

ready
25th March 2011, 08:16
is your question probably about promition if you google it?
Is your answer to this thread is promotion??

BalaQT
25th March 2011, 08:28
hi , u can override the mousPressEvent

void QLabel::mousePressEvent(QMouseEvent *evt)
{
qDebug()<<"X"<<evt->x()<<"Y"<<evt->y();
}

hope it helps
Bala

ready
25th March 2011, 08:33
thanks bala...
but i am getting confused where should i declare the class to override the mousepressevent..
is it in mainwindows.h??

BalaQT
25th March 2011, 08:36
put it in mainwindow.cpp

hope it helps
Bala

MarekR22
25th March 2011, 08:47
hi , u can override the mousPressEvent

void QLabel::mousePressEvent(QMouseEvent *evt)
{
qDebug()<<"X"<<evt->x()<<"Y"<<evt->y();
}

hope it helps
Bala
Do you really think this will compile and link? No comment!


@topic:
The simples way to solve this problem is to install event filter see: QObject::installEventFilter for details.

Another think you are doing common mistake in asking questions!
You giving us ready solution of your problem and asking how to make it work.
First you should explain what you want to achieve then explain how you tried to solve it this problem. I wouldn't be surprised if some would give you a better solution of primary problem.

BalaQT
25th March 2011, 08:53
Do you really think this will compile and link? No comment!

yes it is compiling. whats wrong?
have you try in your end?

bala

MarekR22
25th March 2011, 08:56
does it work?

ready
25th March 2011, 09:02
thanks marek
the event filter class u mentioned above...
do I need to declare this class in mainwindow.cpp(of ui class)

MarekR22
25th March 2011, 09:05
I still think that your approach is totally wrong! QLabel is design just to visualize text not for user interaction. What you are try to do in first place?

BalaQT
25th March 2011, 09:36
@MarekR22

does it work?
yes its working fine , what is wrong?
eventfilter is good too. just i gave a quick reply.

@ready
as marek22 says, what you want to acheive , can u explain?
Bala

Added after 14 minutes:


do I need to declare this class in mainwindow.cpp(of ui class)
this is not class. this is eventfilter. put it in the mainwindow.cpp
bala

ready
25th March 2011, 09:49
how to install eventfilter for getting mouse coordinate from Qlabel.........please provide me detail

BalaQT
25th March 2011, 10:30
hi,

how to install eventfilter for getting mouse coordinate from Qlabel.........please provide me detail

bool MainWindow::eventFilter(QObject *pObject, QEvent *evt)
{
if(pEv->type()==QEvent::MouseButtonDblClick) /* mouse button is doublclicked*/
{
QLabel *lb=qobject_cast<QLabel *>(pObject);
if(lb)
{
QMouseEvent *mEvt=static_cast<QMouseEvent *>(ect);
qDebug()<<"dbl clicked"<<evt->x()<<","<<evt->y();
}
}
}


and use installEventFilter(obj) to install this event filter
ex:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
a.installEventFilter(&w);
return a.exec();
}
hope it helps
bala

FelixB
25th March 2011, 10:33
and don't forget

label->installEventFilter(this);

edit: oh, maybe I should read posts until the end...
edit2: ah, the information was added by edit ;)

BalaQT
25th March 2011, 10:37
@felix:
ha, u and me are posting at the same time,im at 16:4 u r at 16:3 :)
urz is better felix :) label->installEventFilter(this);

bala

MarekR22
25th March 2011, 10:48
// to install main window event filter for label:
MainWidow::MainWidow ....
{
.....
ui->someLabel->installEventFilter(this);
.....
}

bool MainWidow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonDblClick && obj == ui->someLabel) {
QMouseEvent* moseEvent = statc_cast<QMouseEvent*>(event);
QPoint position = moseEvent->pos();
// do something
}
return QMainWidow::eventFilter(obj, event);
}

Still I'm sure this is bad solution for the real problem you hiding from us :).

stampede
25th March 2011, 11:01
I'd rather use dynamic_cast


QMouseEvent *mEvt=dynamic_cast<QMouseEvent *>(ect);
static_cast does not provide runtime checks for casts, so you can create faulty code like this one:


#include <iostream>
#include <vector>
#include <string>

class A{
public:
A(){
}
virtual ~A(){
}
};

class B : public A{
public:
B(){
// add some data to this object, note that there is no such data in objects of class A
for( int x=0 ; x<1000 ; ++x ){
v.push_back(x);
}
s = "a string data";
}
void thisMethodIsNotInA(){
std::cout << "method from B: "<<s << v.size() << " " <<"\n";
}
std::string s;
std::vector<int> v;
};

int main(){
A * a = new A(); // a is a pointer to A
B * b = dynamic_cast<B*>(a); // this will return NULL, because a is not pointer to B
if( b ){
std::cout << "dynamic cast ok ?!\n"; // you should not see this line
}
B * b_static = static_cast<B*>(a);
if( b_static ){
std::cout << "watch out for static_cast !\n"; // probably you'll see this line ...
b_static->thisMethodIsNotInA(); // ... but not this one ;)
}
}

dynamic_cast will check that a is not a B*, so b == NULL, while static_cast will return non-zero pointer and calling the method from B will result in a crash.
I know that it should work in case of QEvents, but up- and down- class casting should be done with dynamic_cast IMHO.

---
edit: tested with recent version of g++ btw.

MarekR22
25th March 2011, 12:47
I'd rather use dynamic_cast
dynamic_cast will check that a is not a B*, so b == NULL, while static_cast will return non-zero pointer and calling the method from B will result in a crash.
I know that it should work in case of QEvents, but up- and down- class casting should be done with dynamic_cast IMHO.

---
edit: tested with recent version of g++ btw.
In this case dynamic_cast is not needed overhead, "if(pEv->type()==QEvent::MouseButtonDblClick) " statement gives you warranty that ect is pointer to QMouseEvent.

stampede
25th March 2011, 13:26
In this case dynamic_cast is not needed overhead, "if(pEv->type()==QEvent::MouseButtonDblClick) " statement gives you warranty that ect is pointer to QMouseEvent
I really doubt that you can feel this overhead in case of mouse press events ( probably depends on how fast you click:P ).
Ok, probably I should write:
up- and down- class casting should be done with dynamic_cast ...... as long as it won't hurt performance

ready
25th March 2011, 14:08
guys please figure out this...I am still having problem
my code are as follows::
main.cpp

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
a.installEventFilter(&w);
return a.exec();
}
and my mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QDebug"
#include "qdebug.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->label->installEventFilter(this);
}
bool MainWindow::eventFilter(QObject *obj, QEvent *e)
{
if (e->type()==QEvent::MouseButtonPress && obj == ui->label)
{

qDebug("User clicked on label");

}
return QMainWindow::eventFilter(obj, e);
}
MainWindow::~MainWindow()
{
delete ui;
}

and mainwindow class

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
bool eventFilter(QObject *obj, QEvent *e);

private:
Ui::MainWindow *ui;
};


#endif // MAINWINDOW_H
ERROR::cannot open output file ..exe

MarekR22
25th March 2011, 14:10
Is it so hard to note that your application is still running or output directory is read only?
It is not code problem.

ready
25th March 2011, 14:13
Is it so hard to note that your application is still running or output directory is read only?
It is not code problem.
no my application is not running at all neither the directory is read only

MarekR22
25th March 2011, 14:19
Then you have to discover yourself why linker doesn't have access to this file. I've given you to most common reasons.

ready
25th March 2011, 14:24
please try to run and see above code in your ui application
and provide me help

FelixB
25th March 2011, 14:35
please provide the *.ui-file, otherwise we can't test your code...

edit @mods: why was this thread moved? It is quite Qt-specific, isn't it?

ready
25th March 2011, 16:46
mu ui file contains only line edit and label

squidge
25th March 2011, 23:02
Ok, but the more work we have to do in order to help you, the less chance you have of actually receiving any help :)

wysota
26th March 2011, 03:34
Sorry, I really can't stop myself. I've seen this from the very beginning but I tried to wait and see how the thread develops but I can't resist anymore from asking, what's the purpose of the two following lines together?


ui->label->installEventFilter(this); // in MainWindow
a.installEventFilter(&w); // in main

I'd like the OP to explain what was the intention behind those two lines.

BalaQT
26th March 2011, 11:08
hi ready,
as wysota mentioned, you need to remove a.installEventFilter(&w); in main.
same code u posted working for me, try to clean and make agian.

hope it helps,
bala