Page 1 of 2 12 LastLast
Results 1 to 20 of 23

Thread: Creating a Pixmap for drag and drop

  1. #1
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Creating a Pixmap for drag and drop

    Hello,

    I would like to drag and drop QFrames around in my own application and I'm wondering if there is a generic way to construct the Pixmaps of the QFrames that are shown when the frame is being dragged. From what I saw so far the Pixmaps are always constructed by hand. Can't I do something like using the QFrame's already existing paintEvent() method to have it paint on a QImage instead and then convert the QImage to a QPixmap? Because then I figure the Pixmap would look just like the frame appears on the screen and that's exactly what I need.

    Thanks
    Cruz

  2. #2
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    what do you need a screenshot of QFrame? if yes, then take a look at QPixmap QPixmap::grabWidget ( QWidget * widget, int x = 0, int y = 0, int width = -1, int height = -1 )
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  3. #3
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    It's not really a screenshot what I want. When you drag something over the screen a pixmap is displayed that moves along with the cursor. When I drag a frame, I want this pixmap to show the very same frame. Just like in the puzzle and the fridgemagnets example. Or when you drag an image in Firefox, you see the very same image just a bit blurred and transparent. It's a really cool effect. And now instead of constructing a pixmap for every kind of draggable widget I have, I would like to find a generic way to construct it. So I guess your suggestion is good! Even if you call it a screenshot. I will look into it shortly.

  4. #4
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    you need to reimplement paintEvent and draw that pixmap.
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  5. #5
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    I tried QPixmap::grabWidget and it only grabs the background. What I draw on the frame in paintEvent is lost.

    Is there really no other way? If I reimplement paintEvent then I have to write the painting code for every different kind of widget twice. Plus the style sheet is not applied, so I have to figure out a way to transfer the style from the widget to the QImage. It's ugly and cumbersome. There must be a generic way.

  6. #6
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    take a look at this example QTDIR/examples/draganddrop/draggableicons
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  7. #7
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    In that example the pixmaps are loaded from images.

  8. #8
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    yes, but you can create needed image and then use it like in that example.
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  9. #9
    Join Date
    Oct 2006
    Location
    New Delhi, India
    Posts
    2,467
    Thanks
    8
    Thanked 334 Times in 317 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    Have a look at QWidget::render
    You can render on to a pixmap which is a paintdevice

  10. #10
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    When creating the images I'm facing the same problem: how to create them in a generic way.

    I'm trying this approach:

    Qt Code:
    1. /* A paint function, that takes a painter as an argument.
    2.  * It's supposed to paint the contents of the frame either
    3.  * on the frame itself or on a pixmap. */
    4. void KeyFrame::myPaint(QPainter* painter)
    5. {
    6. painter->setPen(Qt::black);
    7. painter->drawText(0, 0, "hello Qt");
    8. }
    9.  
    10. /* The frame is drawing itself on the gui. */
    11. void KeyFrame::paintEvent(QPaintEvent *event)
    12. {
    13. QFrame::paintEvent(event);
    14. QPainter painter(this); // Construct a painter that draws on this frame.
    15. myPaint(&painter); // Pass it to my painter.
    16. }
    17.  
    18. /* Drag action starting. */
    19. void KeyFrame::mousePressEvent(QMouseEvent *event)
    20. {
    21. /* Prepare a pixmap for the drag that will be moved along with the mouse. */
    22.  
    23. // Grab the widget so you get a styled background.
    24. QPixmap pixmap = QPixmap::grabWidget(this);
    25.  
    26. // Initialize a painter that draws on the pixmap....
    27. QPainter painter;
    28. painter.begin(&pixmap); // ...and pass it to my painter.
    29. myPaint(&painter);
    30. painter.end();
    31.  
    32. // Create the drag object.
    33. QDrag *drag = new QDrag(this);
    34. drag->setPixmap(pixmap);
    35. }
    To copy to clipboard, switch view to plain text mode 

    But it doesn't work. What I paint on the pixmap is not shown. Do you see an error?

  11. #11
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    Quote Originally Posted by aamer4yu View Post
    Have a look at QWidget::render
    You can render on to a pixmap which is a paintdevice
    That would be perfect! But again, it doesn't work.

    Qt Code:
    1. void KeyFrame::mousePressEvent(QMouseEvent *event)
    2. {
    3. if (event->button() == Qt::LeftButton)
    4. {
    5. // Prepare the mime data for the drag.
    6. QMimeData *mimeData = new QMimeData;
    7. mimeData->setText("hello");
    8.  
    9. QPixmap pixmap(this->size());
    10. this->render(&pixmap);
    11.  
    12. // Create the drag object.
    13. QDrag *drag = new QDrag(this);
    14. drag->setMimeData(mimeData);
    15. drag->setPixmap(pixmap);
    16.  
    17. Qt::DropAction dropAction = drag->exec();
    18. }
    19. }
    To copy to clipboard, switch view to plain text mode 

    The drag starts and all I see is a blank rectangle of the right size, but with the window background color. Not even the frame background color actually. Neither the style is applied, nor are the contents of the frame rendered. Am I not doing something right?

  12. #12
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    try this (modificated draggableicons example)
    Qt Code:
    1. void Test::mousePressEvent(QMouseEvent *event)
    2. {
    3. QPixmap pixmap = QPixmap::grabWidget(this);
    4.  
    5. QByteArray itemData;
    6. QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    7. dataStream << pixmap << QPoint(event->pos());
    8.  
    9. QMimeData *mimeData = new QMimeData;
    10. mimeData->setData("application/x-dnditemdata", itemData);
    11.  
    12. QDrag *drag = new QDrag(this);
    13. drag->setMimeData(mimeData);
    14. drag->setPixmap(pixmap);
    15. drag->setHotSpot(event->pos());
    16.  
    17. QPainter painter(&pixmap);
    18. painter.drawText(pixmap.rect().center().x(), pixmap.rect().center().y(), "hello Qt");
    19.  
    20. drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
    21. }
    To copy to clipboard, switch view to plain text mode 
    NOTE: you must set setAcceptDrops(true) in Test::ctor.
    PS. read more about Drag&Drop
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  13. #13
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    I tried it by copy&paste. It also doesn't work. All I see is a rectangle of the right size and the wrong background color and nothing written on it. Also tried not grabbing the pixmap, but just initializing a blank one and then drawing on it: nothing. Not working. Here is the simplest example I can image:

    Qt Code:
    1. void KeyFrame::mousePressEvent(QMouseEvent *event)
    2. {
    3. QPixmap pixmap = QPixmap(this->size());
    4. QPainter painter(&pixmap);
    5. painter.drawText(pixmap.rect().center().x(), pixmap.rect().center().y(), "hello Qt");
    6.  
    7. QMimeData *mimeData = new QMimeData;
    8. mimeData->setText("hello");
    9.  
    10. QDrag *drag = new QDrag(this);
    11. drag->setMimeData(mimeData);
    12. drag->setPixmap(pixmap);
    13. drag->setHotSpot(event->pos());
    14.  
    15. drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
    16. }
    To copy to clipboard, switch view to plain text mode 

    Not working. I tried amoving the pixmap to the heap, but that doesn't help either. I'm out of ideas.

  14. #14
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    did you set 'setAcceptDrops(true)'?
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  15. #15
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    I can drag and drop the frame into a QLineEdit and it will show whatever I set as text into the MimeData. So I assume this line edit has its accept drops set to true. The drag itself works fine. The problem is only related to what the drag looks like. In particular I don't seem to be able to draw on the pixmap. I don't thing the accept drops has anyhting to do with it.

  16. #16
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    this example works fine for me, but it is not complite, just demo for creating and moving grabbed image.
    Qt Code:
    1. #include <QtGui>
    2. #include "test.h"
    3.  
    4. Test::Test(QWidget *parent)
    5. : QMainWindow(parent)
    6. {
    7. QWidget *widget = new QWidget;
    8. QGridLayout *grid = new QGridLayout(widget);
    9.  
    10. QPushButton *pb = new QPushButton(tr("Button"));
    11. pb->installEventFilter(this);
    12. QComboBox *cb = new QComboBox;
    13. cb->installEventFilter(this);
    14. QCheckBox *chb = new QCheckBox(tr("Check box"));
    15. chb->installEventFilter(this);
    16. QRadioButton *rb = new QRadioButton(tr("Radio button"));
    17. rb->installEventFilter(this);
    18. QSpinBox *sb = new QSpinBox;
    19. sb->installEventFilter(this);
    20. dsp->installEventFilter(this);
    21.  
    22. grid->addWidget(pb, 0, 0);
    23. grid->addWidget(cb, 0, 1);
    24. grid->addWidget(chb, 0, 2);
    25. grid->addWidget(rb, 1, 0);
    26. grid->addWidget(sb, 1, 1);
    27. grid->addWidget(dsp, 1, 2);
    28.  
    29. setCentralWidget(widget);
    30.  
    31. setAcceptDrops(true);
    32. }
    33.  
    34. void Test::mousePressEvent(QMouseEvent *event)
    35. {
    36. processDrag(this, event);
    37. }
    38.  
    39. void Test::processDrag(QWidget *widget, QMouseEvent *event)
    40. {
    41. QPixmap pixmap = QPixmap::grabWidget(widget);
    42. QPainter painter(&pixmap);
    43. painter.setPen(Qt::red);
    44. painter.drawText(0, pixmap.rect().center().y(), "hello Qt");
    45.  
    46. QByteArray itemData;
    47. QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    48. dataStream << pixmap << QPoint(event->pos());
    49.  
    50. QMimeData *mimeData = new QMimeData;
    51. mimeData->setData("application/x-dnditemdata", itemData);
    52.  
    53. QDrag *drag = new QDrag(this);
    54. drag->setMimeData(mimeData);
    55. drag->setPixmap(pixmap);
    56. drag->setHotSpot(event->pos());
    57.  
    58. drag->exec();
    59. }
    60.  
    61. bool Test::eventFilter(QObject *o, QEvent *e)
    62. {
    63. if (e->type() == QEvent::MouseButtonPress) {
    64. QMouseEvent *me = static_cast<QMouseEvent *>(e);
    65. QWidget *widget = qobject_cast<QWidget *>(o);
    66. if (widget && me->button() == Qt::LeftButton) {
    67. processDrag(widget, me);
    68. return true;
    69. }
    70. }
    71.  
    72. return QMainWindow::eventFilter(o, e);
    73. }
    To copy to clipboard, switch view to plain text mode 
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  17. The following user says thank you to spirit for this useful post:

    Cruz (19th January 2009)

  18. #17
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    Wow! Thanks a lot for all the effort you are putting into this. I built a project from your example and it works for me too. Now I need to scrutinize the differences and see which bit is responsible.

  19. #18
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    I found the bugger! It's the style sheet.

    Qt Code:
    1. background-color: beige;
    2. }
    To copy to clipboard, switch view to plain text mode 

    With this I set the bg color of the application. If I take this out, the drag looks like it should. If this is back in, the drag is only a beige rect.

    Why is the style sheet influencing the drag this way? The drag itself is not a widget is it?

    I tried taking this out of my style sheet and explicitly setting the background of my main window (which is a QWidget and not a QMainWindow in my case) in Designer. It has the same bad effect on the drag.

    So the last thing to figure out is how to set a background color for the application AND have nice looking drags.

  20. #19
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    try to use QPalette insted of using style sheets.
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  21. #20
    Join Date
    Jan 2009
    Location
    Germany
    Posts
    363
    Thanks
    87
    Thanked 12 Times in 12 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Creating a Pixmap for drag and drop

    Yes, the palette works. At the end using style sheets brought me more trouble than good. It's nice how you can change the appearance easily by editing a singe style sheet and not even have to recompile for it. But it doesn't look the same on Windows and on Linux and there is troubles like with the drag. There is still nothing like pixel exact coding.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.