Skip to content
  • 0 Votes
    2 Posts
    463 Views
    D

    I finally succeed to create this using 2 MultiPointTouchArea but I had to write drag function on touchUpdated event.

    Here is my code for one drag area:

    import QtQuick 2.0 Item{ id: joystick width: 100 height: 500 Rectangle{ id: joystickPad height: 50 width: 100 MultiPointTouchArea{ property var offset: null anchors.fill:parent minimumTouchPoints: 1 maximumTouchPoints: 1 function dragMove(point) { if (point) { var position = joystick.mapFromItem(joystickPad, point.x, point.y); /* Change y axis */ if((position.y - offset.y) < 0) { /* Do not go on top of drag area */ joystickPad.y = 0; } else { if((position.y - offset.y) > (joystick.height-joystickPad.height)) { /* Do not go below of drag area */ joystickPad.y = (joystick.height-joystickPad.height); } else { joystickPad.y = position.y - offset.y; } } } } onPressed: { var point = touchPoints[0]; offset = Qt.point(point.x, point.y); } onTouchUpdated: { var point = touchPoints[0]; dragMove(point); } onReleased: { //Reset position joystickPad.x = (joystick.width/2 - joystickPad.width/2) joystickPad.y = (joystick.height/2 - joystickPad.height/2) } } } }
  • 1 Votes
    16 Posts
    4k Views
    P

    @mrjj I started this topic because I did not know how to start this project. You and @SGaist advices me and gives to me the right direction where I can go. So I can now start my project. Thank you both!! I think it is now time to close this topic.

  • 0 Votes
    2 Posts
    5k Views
    Diego DonateD

    I have changed the structure, I have used a QQuickWidget with a QML inside, and now I have what I wanted. Here is my code in case anyone needs something similar

    main.cpp

    ... MovableWidget *view = new MovableWidget; view->setSource(QUrl("qrc:/Test.qml")); view->setWindowFlags(Qt::FramelessWindowHint); view->show(); ...

    Test.qml

    import QtQuick 2.0 Rectangle { id: myWindow width: 500; height: 500 color: "yellow" Rectangle { anchors.centerIn: parent width: 200; height: 200 color: "red" } }

    MovableWidget.cpp

    #include "movableWidget.h" #include <QMouseEvent> // ************************************************** ************************** MovableWidget::MovableWidget(QWidget *parent) : QQuickWidget(parent), m_previousPos(0,0) { installEventFilter(this); } // ************************************************** ************************** bool MovableWidget::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseButtonPress) { m_previousPos = QCursor:os(); } else if (event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); if(mouseEvent->buttons() == Qt::LeftButton) { QPoint offset = m_previousPos - QCursor:os(); m_previousPos = QCursor:os(); move(pos() - offset); } } return false; }
  • 0 Votes
    14 Posts
    12k Views
    mrjjM

    Hi
    Sounds ok to me. another signal based version of widgetAt :)

  • 0 Votes
    1 Posts
    876 Views
    No one has replied
  • 0 Votes
    5 Posts
    2k Views
    mrjjM

    @Vagabond
    Heh. good work.

    Just as a note:
    you can use event filters to implement drag and drop on other widgets if
    no other need to subclass them.

    http://ynonperek.com/course/qt/event-filter2.html

    But for your case, subclassing QGroupBox is super.

  • 0 Votes
    6 Posts
    9k Views
    A

    Had a similar Issue. Was able to find a solution. Below is a generic PyQt5 example that solves the problem using right click.

    import sys from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * class Tabs(QTabWidget): def __init__(self, parent): super().__init__(parent) self.parent = parent self.setAcceptDrops(True) self.tabBar = self.tabBar() self.tabBar.setMouseTracking(True) self.indexTab = None self.setMovable(True) self.addTab(QWidget(self), 'Tab One') self.addTab(QWidget(self), 'Tab Two') def mouseMoveEvent(self, e): if e.buttons() != Qt.RightButton: return globalPos = self.mapToGlobal(e.pos()) tabBar = self.tabBar posInTab = tabBar.mapFromGlobal(globalPos) self.indexTab = tabBar.tabAt(e.pos()) tabRect = tabBar.tabRect(self.indexTab) pixmap = QPixmap(tabRect.size()) tabBar.render(pixmap,QPoint(),QRegion(tabRect)) mimeData = QMimeData() drag = QDrag(tabBar) drag.setMimeData(mimeData) drag.setPixmap(pixmap) cursor = QCursor(Qt.OpenHandCursor) drag.setHotSpot(e.pos() - posInTab) drag.setDragCursor(cursor.pixmap(),Qt.MoveAction) dropAction = drag.exec_(Qt.MoveAction) def dragEnterEvent(self, e): e.accept() if e.source().parentWidget() != self: return print(self.indexOf(self.widget(self.indexTab))) self.parent.TABINDEX = self.indexOf(self.widget(self.indexTab)) def dragLeaveEvent(self,e): e.accept() def dropEvent(self, e): print(self.parent.TABINDEX) if e.source().parentWidget() == self: return e.setDropAction(Qt.MoveAction) e.accept() counter = self.count() if counter == 0: self.addTab(e.source().parentWidget().widget(self.parent.TABINDEX),e.source().tabText(self.parent.TABINDEX)) else: self.insertTab(counter + 1 ,e.source().parentWidget().widget(self.parent.TABINDEX),e.source().tabText(self.parent.TABINDEX)) class Window(QWidget): def __init__(self): super().__init__() self.TABINDEX = 0 tabWidgetOne = Tabs(self) tabWidgetTwo = Tabs(self) layout = QHBoxLayout() self.moveWidget = None layout.addWidget(tabWidgetOne) layout.addWidget(tabWidgetTwo) self.setLayout(layout) if __name__ == '__main__': app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
  • 0 Votes
    4 Posts
    3k Views
    raven-worxR

    @AliReza-Beytari

    So to enable drops to the filesystem you should add a file urls (using QMimeData::setUrls() for example).
    For photoshop it might be enough to set a image on the mimedata (using QMimeData::setPixmap())

    Take a look at the Delayed encoding example.

    The interesting part here is the QMimeData::retrieveData() overload. This method gets called when a drop happens.

    So when a drop to the filesystem happens the mimedata requests the data and calls retrieveData(). In there you write your pixmap data to a temporary image file. For that you can use QTemporaryFile class for example. Write the data to the temporary file and return the url to the file. Mime-Type: "text/uri-list"

    Analog for the pixmap image. Simply return the QPixmap. Mime-Type: "image/png"
    Actually it could also be necessary to return the PNG binary data. I am not sure. This can be done like this:

    QPixmap pixmap; QByteArray data; QBuffer buffer(&data); buffer.open(QIODevice::WriteOnly); pixmap.save(&buffer, "PNG"); buffer.close();

    The advantage of this approach is that you only create the drop data when necessary. Especially the temp file used for drops to the filesystem.

  • 0 Votes
    4 Posts
    3k Views
    mrjjM

    HI
    so rootItem is your "drop" widget?
    Is the yellow on picture rootitem or the white one where mouse is? ( A=8 )

    It does look correct so a bit odd.

    and
    void dragEnterEvent(QDragEnterEvent* event) Q_DECL_OVERRIDE;

    should be called when u leave this small area.

    I assume you are 100% sure that is not called and its not just
    the change to while part that is failing.

    I can't guess from this little code what could be wrong.sorry.

    Just for test, could you run my editor and see it does indeed say
    "drag leave" when u drag from the list on the left to center.

    https://www.dropbox.com/s/ikra7pm161lzf56/DMDesigner.zip?dl=0

  • 0 Votes
    3 Posts
    2k Views
    D

    @SGaist Thanks Champion! I will try !

  • 0 Votes
    10 Posts
    7k Views
    V

    Well, I found solution. It is very simple, all I need is to set default drop action for my view class as Qt::MoveAction and return copy and move in the suporrtedDropActions().

  • 0 Votes
    8 Posts
    4k Views
    J

    @Jakob Hm, it seems I didn't refresh - you already did mark as solved - my apologies