PDA

View Full Version : Showing an QImage doubleclicked from QMouseEvent inside a QLabel



Momergil
18th October 2011, 16:57
Hello!

I never used QMouseEvent before and now I'm trying to learn how to do it, but till now I'm unable to be sucessfull. What I want to do is:

I'm showing a movie (or else only one image) that consists in a series of images inside a QLabel that change over time due to a QTimer clock. Since the images shown are offently resized to fit in the QLabel's size, I want to add the possibility for the user to left double click in the image (or else in the QLabel, ether works) and a QDialog should appear, showing the imagem inside, while the movie should stop. When the QDialog is destroyed, the movie should continue.

Till now what I did was essentially to copy from an example and the code almost worked. Here it is:


void MainWindow::mousePressEvent(QMouseEvent *event)
{
QLabel *child = static_cast<QLabel*>(childAt(event->pos()));
if (!child)
qDebug() << "Problem!!!!!";
else if (event->button() == Qt::LeftButton)
{
timer.stop();
QDialog qd;
connect(&qd,SIGNAL(destroyed()),this,SLOT(restartTimer()));
child->setParent(&qd);
qd.exec();
}
}

void MainWindow::restartTimer()
{
timer.start(1000);
}


The problem with this code is that the childAt() and setParent() functions seems not to "copy" the image inside the QLabel, but to TAKE it away - so while displaying the QDialog the QLabel in which was the image turns empty. As if that wasn't enough, when the timer restarts and its time for the new image to be shown, the software crash, since the QLabel in which the new image was supposed to appear was cut from its original place and put in the QDialog.

No to mension that I wasn't able to understand how can I identify if the press event is a DoubleClick and at the same type if it is with the Left Button.


So could somebody give me a typ, please?

Thanks!


Momergil

stampede
18th October 2011, 18:45
QDialog qd;
connect(&qd,SIGNAL(destroyed()),this,SLOT(restartTimer()));
child->setParent(&qd);
qd.exec();
When exec() returns, qd goes out of scope. Since its QObject-based, it will attempt to delete all its childrens, including "child" QLabel.
What you should do is to create new QLabel (or any other widget to display image) and show the image there, something like:


timer.stop();
QDialog qd;
QLabel * label = new QLabel(&qd);
//...
// create a layout or something, put the label there, set it to QDialog etc...
//...
if( const QPixmap * p = child->pixmap() )
label->setPixmap(*p);
connect(&qd,SIGNAL(destroyed()),this,SLOT(restartTimer()));
qd.exec();



No to mension that I wasn't able to understand how can I identify if the press event is a DoubleClick and at the same type if it is with the Left Button
use event->button() method.

Momergil
18th October 2011, 19:48
Hello, stampede!

Thanks for the tip; the code works.

Now two problem remains:

1) As I show in the first code, I did try to use "event->button()" method, but I couldn't find how to put it in the code so it would look after double clicks event. Anyway, I used "if (event->type() == QMouseEvent::MouseButtonDblClick)" and it worked.

2) In my code, the images being shown in the original QLabel have being rezised; the originals are normally bigger. Now, when it comes about showing the QDialog, I want to show the originals, in theyr full, normal size, not as shown in the QLabel. Now how do I do this? Technically I must create an algorithm that somehow itendifies the name of the image being shown, look it again in the Resource files (where all the images are) and show that in the QDialog. Or is there another way of doing that?


Thanks!

Momergil


Edit: Notice that I can't get the name of the image (the name as it is in the Resource file). here is how I get the image to put it in the original QLabel (actually, is only part of the conde, but enough to understand):


QImage image(file.fileName());

l_images.push_back(image);

ui->Image->setPixmap(QPixmap::fromImage(newDimension(l_images[0])));


QImage MainWindow::newDimension(QImage image)
{
nova_imagem;

if (image.height() > ui->Image->height())
nova_imagem = image.scaledToHeight(ui->Image->height());

if (image.width() > ui->Image->width())
nova_imagem = image.scaledToWidth(ui->Image->width());

return nova_imagem;
}

Momergil
19th October 2011, 12:41
News: I solved my own problem. Here is the code:


void MainWindow::mousePressEvent(QMouseEvent *event)
{
if ((event->type() == QMouseEvent::MouseButtonDblClick) && (event->button() == Qt::LeftButton))
{
timer.stop();
QLabel *child = static_cast<QLabel*>(childAt(event->pos()));

if( const QPixmap * p = child->pixmap() )
{
QDialog dialog;
connect(&dialog,SIGNAL(destroyed()),this,SLOT(restartTimer( )));
QLabel * label = new QLabel(&dialog);

QPixmap a = QPixmap::fromImage(imagemsemred);
label->setPixmap(a);
dialog.resize(a.size());
dialog.exec();
}
}
}

QImage MainWindow::newDimension(QImage image)
{
imagemsemred = image;
nova_imagem = image;

if (image.height() > ui->Image->height())
nova_imagem = image.scaledToHeight(ui->Image->height());

if (image.width() > ui->Image->width())
nova_imagem = image.scaledToWidth(ui->Image->width());

return nova_imagem;
}

The only problem is that I don't know what to do with that "p", since I don't use it as a variable but Its necessary for the software only allows mouse events over the Label.


Thanks for everything,

Momergil