Drag n Drop Button and Drop-down menu PyQt/Qt designer

前端 未结 4 2059
悲&欢浪女
悲&欢浪女 2020-12-11 11:27

I would like to know the \"best practice\" to change the behavior of some buttons to do the following:

I want with a click to appear a menu. Or when you drag this sa

4条回答
  •  星月不相逢
    2020-12-11 12:03

    You need to use a QDropEvent, I know this is not a very good answer but just create a QDropEvent function and in that function check the dropped button.

    If firstButton's dropped on secondButton, painter->drawLine(firstButton.pos(), secondButton.pos()); You can use other points for drawing the line. Or you can use event->source() for the dragged button. You might need to define a QPen with some settings. When I say other points to use, I mean like firstButton.boundingRect().topRight().x(), firstButton.boundingRect.bottomRight().y() - firstButton.boundingRect.height() / 2

    See: http://doc.qt.io/qt-5/qdropevent.html

    Sorry, this code is pseudo C++ code, but you can easily adapt it to Python.

    Example:

     void MainWindow::dropEvent(QDropEvent *event)
     {
         if(event->pos() == somePoint) //somePoint should be inside target's boundingRect, you need to write basic collision detection
              painter->drawLine(event->source().pos(), event->pos()); //You might use other points
     }
    

    There are other drag and drop events also. You can change the target's color for example if dragged over it. See http://doc.qt.io/qt-5/dnd.html

    I can try to help with collision detection code if you need it. I don't know if there's better way though. There may be. I'm mostly a C++ coder, but I can provide basic examples.

    And the dropdown menu. You can create a simple QWidget with your menu with some mouseEvents and make it a child of the button, and set the y position of it so it shows under the button. For example (Again, C++, sorry):

     dropDownMenu->setParent(someButton);
     dropDownMenu->setPos(someButton.x(), someButton.y() + someButton.boundingRect().height());
    

    You can hide or show it with mouseReleaseEvent. Just make sure to hide it back in your dropEvent function, so when you drag and drop it, it doesn't show.

    Edit: Let me show you a simple collision detection code in C++, but easily adaptable to Python.

     if(event->pos() > target.boundingRect().topLeft().x() && event->pos() < target.topRight.x() && event->pos() > target.boundingRect().topRight() && event->pos() < target.boundingRect().bottomRight()) {
          //It's on the button.
     }
    

    If you want a simpler solution. Just subclass the buttons you're going to drop onto and add the drag and drop events in their class. This would be easier, and shorter. I think dropEvent should work in a subclass too. I haven't tried it.

    Edit: If you're asking how to do all of them using only Qt Designer, you can't. You need to write some code. You can't develop programs with Qt Designer, it's just for making the ui more easily. You can make software without Qt Designer, but you can't make software with only Qt Designer. You'll need to learn a bit of Python programming and a bit of PyQt for tasks like this. But both Python and Qt are easy enough to get the hang of them in a short time, and Qt documentation is marvellous.

    Good luck!

提交回复
热议问题