PDA

View Full Version : Custom widget for QtCreator, QLabel problem



mih90
24th August 2013, 16:58
Hi,
I'm trying to implement a drag-and-drop feature in my application, so I created couple widgets as QtDesginer plugins, co i can put those visually in QtCreator.
First widget is an Icon widget which should be draggable and second widget is a container from which icons should be dragged over to another widget.

Icon widget is created as QWidget with vertical layout and two QLabel objects - one for QPixmap icon and second for displaying name.

here is the code for the icon widget :



#ifndef DRAGGABLEICONWIDGET_H
#define DRAGGABLEICONWIDGET_H

#include <QWidget>
#include <QFrame>
#include <QLabel>
#include <QMetaProperty>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPixmap>

class DraggableIconWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(QString group READ group WRITE setGroup)
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(QString displayName READ displayName WRITE setDisplayName)
Q_PROPERTY(QPixmap icon READ icon WRITE setIcon)
public:
DraggableIconWidget(QWidget *parent = 0);

QString group();
void setGroup(QString);

QString name();
void setName(QString);

QString displayName();
void setDisplayName(QString);

QPixmap icon();
void setIcon(QPixmap);
private:
QString group_;
QString name_;
QString displayName_;
QPixmap icon_;

QLabel *iconLabel_;
QLabel *nameLabel_;
QVBoxLayout *layout_;
};

#endif



#include "draggableiconwidget.h"

DraggableIconWidget::DraggableIconWidget(QWidget *parent) :
QWidget(parent)
{
iconLabel_ = new QLabel();
iconLabel_->setAlignment(Qt::AlignCenter);
iconLabel_->setText("");

nameLabel_ = new QLabel();
nameLabel_->setAlignment(Qt::AlignCenter);
nameLabel_->setText("name");

layout_ = new QVBoxLayout(this);
layout_->addWidget(iconLabel_);
layout_->addWidget(nameLabel_);

this->setLayout(layout_);
}

QString DraggableIconWidget::group()
{
return this->group_;
}
void DraggableIconWidget::setGroup(QString s)
{
this->group_ = s;
}
QString DraggableIconWidget::name()
{
return this->name_;
}
void DraggableIconWidget::setName(QString s)
{
this->name_ = s;
}
QString DraggableIconWidget::displayName()
{
return this->displayName_;
}
void DraggableIconWidget::setDisplayName(QString s)
{
this->displayName_ = s;
this->nameLabel_->setText(this->displayName_);
}
QPixmap DraggableIconWidget::icon()
{
//this works fine in creator
//return this->icon_;
if(!this->iconLabel_->pixmap())
return QPixmap();
return *this->iconLabel_->pixmap();
}
void DraggableIconWidget::setIcon(QPixmap p)
{
//this->icon_ = p;
this->iconLabel_->setPixmap(p);
}


and here is the code for dragging function in the second custom widget:



void DragWidget::mousePressEvent(QMouseEvent *e)
{
DraggableIconWidget *widget = static_cast<DraggableIconWidget*>(childAt(e->pos()));
if(!widget)
return;

QPixmap pixmap = widget->icon(); //it crash here
QString data = widget->group() + ":" + widget->name();

QMimeData *mimeData = new QMimeData();
mimeData->setText(data);

QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(pixmap);
drag->setHotSpot(e->pos() - widget->pos());

QPixmap tempPixmap = *widget->iconLabel()->pixmap();
QPainter painter;
painter.begin(&tempPixmap);
painter.fillRect(pixmap.rect(),QColor(127,127,127, 127));
painter.end();

if(drag->exec(Qt::CopyAction | Qt::MoveAction,Qt::CopyAction) == Qt::MoveAction)
{
widget->close();
}
else {
widget->show();
widget->setIcon(pixmap);
}
}


the problem is with getting the pixmap back from QLabel object. if the icon() function which return the pixmap, would be without the if statment the QtCreator is crashing everytime I try to open *.ui file and the same thing is when i'm trying to get the pixmap from item in my custom frame widget for dragging.

It works fine in QtCreator (loads .ui files and i can change the object icon) when i'm using second variable QPixmap icon_ in the class, and in the icon() function i return the this->icon_ variable, but then it also will crash when I'm trying to obtain pixmap form within the second widget.

Previously i was using my own widget for icons, but It was based on QLabel object, and then dragging and everything else was fine, but then i can't add second label with text so I must find another way for doing it.

here is the stack dump:


0 QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData> >::data qscopedpointer.h 135 0xe27a2e
1 qGetPtrHelper<QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData> > > qglobal.h 2455 0xa73637
2 QLabel::d_func qlabel.h 166 0xe5add8
3 QLabel::pixmap qlabel.cpp 437 0xa6e575
4 DraggableIconWidget::icon draggableiconwidget.cpp 48 0x401d16
5 DragWidget::mousePressEvent dragwidget.cpp 14 0x4015bb
6 QWidget::event qwidget.cpp 8371 0x6d6370
7 QFrame::event qframe.cpp 557 0xa6ac28
8 QApplicationPrivate::notify_helper qapplication.cpp 4562 0x68bf46
9 QApplication::notify qapplication.cpp 4105 0x68a190
10 QCoreApplication::notifyInternal qcoreapplication.cpp 946 0x69dd5a1a
11 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 234 0xd2653a
12 QApplicationPrivate::sendMouseEvent qapplication.cpp 3171 0x6889fc
13 QETWidget::translateMouseEvent qapplication_win.cpp 3365 0x6f31a9
14 QtWndProc@16 qapplication_win.cpp 1698 0x6edf9e
15 USER32!GetDC C:\WINDOWS\system32\user32.dll 0x7e368734


To compile my custom widgets I used Qt 4.84 with MSVC compiler, and for building my test application i'm using Qt 4.8.4 with MinGw compiler
Everything was tested in QtCreator 2.8.0

Any ideas what could be wrong with my code ? Thnx in advance for any clues ;)

Santosh Reddy
26th August 2013, 13:03
A quick change to aviod crashing.


//DraggableIconWidget *widget = static_cast<DraggableIconWidget*>(childAt(e->pos()));
DraggableIconWidget *widget = dynamic_cast<DraggableIconWidget*>(childAt(e->pos()));
if(!widget)
return;

Also note that static_cast does not set the widget to 0 if the types are uncompatible, dynamic_cast is supposed to be used here.