Custom widget for QtCreator, QLabel [->pixmap()] problem [SOLVED]
-
Hi,
I'm trying to implement drag and drop feature in my application. To do this I created two widgets as QtDesigner(Creator) plugins. One of the widgets is the draggable icon with text (two QLabels), and the second one is container based on QFrame with implemented dragging functionality. The problem is with the first widget, QtCreator crashes when I'm opening any *.ui file, even the ones from other projects so i assume there is something wrong with the plugin ithself. My application also crashes when after clicking on the icon - which executes the functions that needs to obtain QPixmap from QLabel inside clicked object. I Checked this with debugger and it always stops on the
@QPixmap pixmap = widget->icon();@Here is code for my custom draggable icon widget :
[draggableiconwidget.h]
@#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_;QLabel *iconLabel_; QLabel *nameLabel_; QVBoxLayout *layout_;
};
#endif
@
[draggableiconwidget.cpp]
@#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()
{
return *this->iconLabel_->pixmap();
}
void DraggableIconWidget::setIcon(QPixmap p)
{
this->iconLabel_->setPixmap(p);
}
@
And here is the code for the function that read the QPixmap from clicked object
@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); }
}@
And the stack dump after debugging:
@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
@Plugins were build with Qt 4.8.4 MSVC version, I'm using QtCreator 2.8.0.
Any ideas what could be wrong there, with getting that QPixmap back from QLabel widget ?
Also when i change the icon() and setIcon() functions like this :
@
QPixmap DraggableIconWidget::icon()
{
return this->icon_;
}
void DraggableIconWidget::setIcon(QPixmap p)
{
this->icon_ = p;
this->iconLabel_->setPixmap(p);
}
@where icon_ is declared as QPixmap icon_; QtCreator works fine and I can change the Icon and all QString parameters of the widget inside QtCreator, but then my application still crashes at the same point - icon() function.
-
Hi,
You should replace your static_cast with a qobject_cast.
static_cast doesn't do any run-time type check so you might end with an invalid pointer.
-
Thanks it works ! ;D I was struggling with it whole day and it was that simple :)
When I was clicking on icon or text below the icon in my custom container widget the object type returned from e->pos was QLabel, not DraggableIconWidget, that's why the application was crashing all the time.
In casy anybody would have similiar problems in the future, I solved it like this:
@
DraggableIconWidget widget;
widget = qobject_cast<DraggableIconWidget>(childAt(e->pos()));
if(!widget){
QLabel temp = qobject_cast<QLabel>(childAt(e->pos()));
if(temp)
{
widget = qobject_cast<DraggableIconWidget*>(temp->parent());
if(!widget)
return;
}else return;
}
@ -
I'm just realizing... Aren't you reinventing QListView in Icon mode ?