PDA

View Full Version : Drag and Drop With Overlaying QWidget



frankiefrank
26th June 2013, 16:22
I have a QTableView with a transparent widget overlayed on top of it. It's basically a watermark-label that tells the user what he should do to fill the table.

The overlay widget is uses this
setAttribute(Qt::WA_TransparentForMouseEvents);.

I then control its visibility based on whether the table has rows.

Now, when the table is empty and the overlay label is displayed, I have a problem with dropping new items into the table. Even though the widget is "transparent for mouse events", when its visible I can no longer drop items.

I think the solution lies in implementing the dragEnterEvent / dropEvent on the widget - but with my experimenting, I didn't manage to find the right one.

Ideally, I would like to hide the overlay widget when I enter drag, show it if I exit drag, but if I drop something inside I would like the parent widget to process the whole thing, as if I dragged and dropped inside it. Preferably without subclassing QTableView.

Some Code:


//OverlayLabel.h
class OverlayLabel : public QWidget
{
Q_OBJECT

public:
OverlayLabel(QWidget *parent = 0);
~OverlayLabel();

int labelFontSizePoints();
void setLabelFontSizePoints(int newSize);
QString labelText();
void setLabelText(const QString &newLabelText);
void setDashBorderVisible(bool isVisible);

void resizeByParent();

private:
static const QString LABEL_HTML_TEMPLATE;
static const QString DASH_BORDER_CSS;

void refreshLabel();

int mFontSizePoints;
QString mLabelPlainText;
Ui::OverlayLabel ui; // the ui is the label surrounded by four spacers making sure it's pushed to the center
};




//OverlayLabel.cpp

#include "overlaylabel.h"

const QString OverlayLabel::LABEL_HTML_TEMPLATE = "<html><head/><body><p><span style=\" font-size:%0pt;\">%1</span></p></body></html>";
const QString OverlayLabel::DASH_BORDER_CSS = "padding: 10px; border: 2px dashed grey";

OverlayLabel::OverlayLabel(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
setPalette(Qt::transparent);

setAttribute(Qt::WA_TransparentForMouseEvents);

setAcceptDrops(true);
mFontSizePoints = 16;
}

OverlayLabel::~OverlayLabel()
{
}

int OverlayLabel::labelFontSizePoints()
{
return mFontSizePoints;
}

void OverlayLabel::setLabelFontSizePoints(int newSize)
{
mFontSizePoints = newSize;
refreshLabel();
}

QString OverlayLabel::labelText()
{
return mLabelPlainText;
}

void OverlayLabel::setLabelText(const QString &newLabelText)
{
mLabelPlainText = newLabelText;
refreshLabel();
}

void OverlayLabel::setDashBorderVisible(bool isVisible)
{
ui.label->setStyleSheet(isVisible ? DASH_BORDER_CSS : QString());
}

void OverlayLabel::resizeByParent()
{
resize(parentWidget()->size());
}

void OverlayLabel::refreshLabel()
{
ui.label->setText(LABEL_HTML_TEMPLATE.arg(mFontSizePoints).a rg(mLabelPlainText));
}

void OverlayLabel::dragEnterEvent(QDragEnterEvent *event)
{
//ui.label->setVisible(false);
//event->acceptProposedAction();
}

void OverlayLabel::dragLeaveEvent(QDragLeaveEvent *event)
{
//ui.label->setVisible(true);
//event->accept();
}

void OverlayLabel::dropEvent(QDropEvent *event)
{
//ui.label->setVisible(true);
//setVisible(false);
//event->accept();
}





//usage:
editorOverlay = new OverlayLabel(/* my tableview */);
editorOverlay->setLabelText(tr("Drop Items Here"));
editorOverlay->setDashBorderVisible(true);