Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Starting a drag stops widget from receiving mouseMoveEvent().

    General and Desktop
    1
    3
    2086
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      blueblood last edited by

      Hello Qt guys.

      My application does image dragging and dropping. And I wanted to have the image being dragged to be visible under the mouse cursor and also be partially transparent, like the many commercial applications out there.

      I really can't find a solution anywhere. There are some similar questions on the internet but they are unanswered or I can't get them to work. like "here":http://www.developer.nokia.com/Community/Wiki/Archived:Transparent_QPixmap_picture and "here":http://qt-project.org/faq/answer/how_can_i_have_a_partially_transparent_pixmap_on_my_toplevel_window
      .
      Obviously, QDrag::setPixmap() won't allow transparency (to my knowledge) and looks ugly.
      So, I had another idea. When dragging starts, I show a QLabel with the dragged image in it, painted partially transparent, and move the image with the mouse position. When mouse is released, I hide the image label.

      Here is a sample code (PySide):
      @class TransparentImageLabel(QtGui.QLabel):
      def init(self, image, parent=None):
      super().init(parent)
      self.setPixmap(image)
      self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
      self.setWindowFlags(QtCore.Qt.FramelessWindowHint)

      def paintEvent(self, e):-
          painter = QtGui.QPainter(self)
          painter.setOpacity(.5)
          painter.drawPixmap(self.pos().x(), self.pos().y(), self.pixmap())
          painter.end()
      

      class DragSource(QtGui.QLabel):
      def init(self, image, parent=None):
      """
      An image label. When mouse is dragged over it,
      shows another small label moving with cursor.
      """
      super().init(parent)
      self.setPixmap(QtGui.QPixmap(image))
      self.tr_label = TransparentImageLabel(image, parent=self)

      def mouseMoveEvent(self, e):
          #drag an image from this label
          mime_data = QtCore.QMimeData()
          mime_data.setImageData(self.pixmap())
          drag = QtGui.QDrag(self)
          drag.setMimeData(mime_data)
          drag.start()
          self.tr_label.show()
          pixmap_width = self.pixmap().width()
          pixmap_height = self.pixmap().height()
          #move label with mouse moves
          self.tr_label.setGeometry(e.pos().x(), e.pos().y()  , pixmap_width , pixmap_height)
          super().mouseMoveEvent(e)
      
      def mouseReleaseEvent(self, e):
          self.tr_label.hide()
      

      class DropTarget(QtGui.QWidget):
      def init(self, parent=None):
      super().init(parent)
      self.layout = QtGui.QVBoxLayout()
      self.image_label = QtGui.QLabel('Drop here!')
      self.layout.addWidget(self.image_label)
      self.setLayout(self.layout)
      self.setAcceptDrops(True)

      def dragEnterEvent(self, e):
          if e.mimeData().hasImage():
              e.accept()
          else:
              e.ignore()
      
      def dropEvent(self, e):
          self.image_label.setPixmap(e.mimeData().imageData())
      

      class Application(QtGui.QWidget):
      def init(self, parent=None):
      super().init(parent)
      self.layout = QtGui.QVBoxLayout()
      self.layout.addWidget(DragSource(r'C:\image.jpg'))
      self.layout.addWidget(DropTarget())
      self.setLayout(self.layout)

      app = QtGui.QApplication(sys.argv)
      main = Application()
      main.show()
      sys.exit(app.exec_())
      @

      It works in that a transparent image is being dragged with the mouse.
      The problem is, when I start the drag (line 31), the label holding the image stops receiving mouseMoveEvents, which also kills the image moving capability. If I comment out the line, the image moves, but I can't drop anything, since I already disabled dragging.
      This might seem logical, as starting dragging should generate dragMoveEvents instead, but nah, no such events get generated.

      Sorry for the long post :-(
      Please help the community solve this problem once and for all :-) . I'd accept modifications on my code or a completely different solution.

      Thanks a lot.

      1 Reply Last reply Reply Quote 0
      • B
        blueblood last edited by

        I also tried QLabel::grabMouse() function in the hope that it will keep the widget receiving events, but instead it locked the GUI and prevented receiving further events.
        Is this a bug within Qt or is it actually a bug in Qt?

        1 Reply Last reply Reply Quote 0
        • B
          blueblood last edited by

          Somebody say something?.
          Is it me, or is it QTea?

          1 Reply Last reply Reply Quote 0
          • First post
            Last post