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
Qt Code:
  1. setAttribute(Qt::WA_TransparentForMouseEvents);
To copy to clipboard, switch view to plain text mode 
.

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:
Qt Code:
  1. //OverlayLabel.h
  2. class OverlayLabel : public QWidget
  3. {
  4. Q_OBJECT
  5.  
  6. public:
  7. OverlayLabel(QWidget *parent = 0);
  8. ~OverlayLabel();
  9.  
  10. int labelFontSizePoints();
  11. void setLabelFontSizePoints(int newSize);
  12. QString labelText();
  13. void setLabelText(const QString &newLabelText);
  14. void setDashBorderVisible(bool isVisible);
  15.  
  16. void resizeByParent();
  17.  
  18. private:
  19. static const QString LABEL_HTML_TEMPLATE;
  20. static const QString DASH_BORDER_CSS;
  21.  
  22. void refreshLabel();
  23.  
  24. int mFontSizePoints;
  25. QString mLabelPlainText;
  26. Ui::OverlayLabel ui; // the ui is the label surrounded by four spacers making sure it's pushed to the center
  27. };
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. //OverlayLabel.cpp
  2.  
  3. #include "overlaylabel.h"
  4.  
  5. const QString OverlayLabel::LABEL_HTML_TEMPLATE = "<html><head/><body><p><span style=\" font-size:%0pt;\">%1</span></p></body></html>";
  6. const QString OverlayLabel::DASH_BORDER_CSS = "padding: 10px; border: 2px dashed grey";
  7.  
  8. OverlayLabel::OverlayLabel(QWidget *parent)
  9. : QWidget(parent)
  10. {
  11. ui.setupUi(this);
  12. setPalette(Qt::transparent);
  13.  
  14. setAttribute(Qt::WA_TransparentForMouseEvents);
  15.  
  16. setAcceptDrops(true);
  17. mFontSizePoints = 16;
  18. }
  19.  
  20. OverlayLabel::~OverlayLabel()
  21. {
  22. }
  23.  
  24. int OverlayLabel::labelFontSizePoints()
  25. {
  26. return mFontSizePoints;
  27. }
  28.  
  29. void OverlayLabel::setLabelFontSizePoints(int newSize)
  30. {
  31. mFontSizePoints = newSize;
  32. refreshLabel();
  33. }
  34.  
  35. QString OverlayLabel::labelText()
  36. {
  37. return mLabelPlainText;
  38. }
  39.  
  40. void OverlayLabel::setLabelText(const QString &newLabelText)
  41. {
  42. mLabelPlainText = newLabelText;
  43. refreshLabel();
  44. }
  45.  
  46. void OverlayLabel::setDashBorderVisible(bool isVisible)
  47. {
  48. ui.label->setStyleSheet(isVisible ? DASH_BORDER_CSS : QString());
  49. }
  50.  
  51. void OverlayLabel::resizeByParent()
  52. {
  53. resize(parentWidget()->size());
  54. }
  55.  
  56. void OverlayLabel::refreshLabel()
  57. {
  58. ui.label->setText(LABEL_HTML_TEMPLATE.arg(mFontSizePoints).arg(mLabelPlainText));
  59. }
  60.  
  61. void OverlayLabel::dragEnterEvent(QDragEnterEvent *event)
  62. {
  63. //ui.label->setVisible(false);
  64. //event->acceptProposedAction();
  65. }
  66.  
  67. void OverlayLabel::dragLeaveEvent(QDragLeaveEvent *event)
  68. {
  69. //ui.label->setVisible(true);
  70. //event->accept();
  71. }
  72.  
  73. void OverlayLabel::dropEvent(QDropEvent *event)
  74. {
  75. //ui.label->setVisible(true);
  76. //setVisible(false);
  77. //event->accept();
  78. }
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. //usage:
  2. editorOverlay = new OverlayLabel(/* my tableview */);
  3. editorOverlay->setLabelText(tr("Drop Items Here"));
  4. editorOverlay->setDashBorderVisible(true);
To copy to clipboard, switch view to plain text mode