Drag&drop in other window
-
I have widget that in normal state (not fullscreen) fine process dragEnterEvent(...) and dropEvent(...), but in fullscreen mode widget doesn't invoke these event handlers. May be somebody has assumption, what can be wrong?
Code snippet for on fullscreenMode:#include <QApplication> #include <QMainWindow> #include <QWidget> #include <QTextEdit> #include <QHBoxLayout> #include <QCheckBox> #include <QDebug> class Widget : public QTextEdit { public: Widget(QWidget* parent = nullptr) : QTextEdit(parent) { setAcceptDrops(true); setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_AcceptTouchEvents); setAutoFillBackground(false); setUpdatesEnabled(true); setFocusPolicy(Qt::StrongFocus); setMouseTracking(true); setTabletTracking(true); } void turnOnFullscreen() { if (!windowState().testFlag(Qt::WindowFullScreen)) { setParent(nullptr); show(); showFullScreen(); activateWindow(); raise(); setFocus(); } } }; class MMainWindow : public QMainWindow { public: MMainWindow(QWidget* parent = nullptr) : QMainWindow(parent) { QHBoxLayout* layout = new QHBoxLayout(this); Widget* textEdit = new Widget(this); QCheckBox* checkBox = new QCheckBox("Fullscreen mode", this); QTextEdit* dragText = new QTextEdit("Text for drag and drop", this); dragText->setReadOnly(true); connect(checkBox, &QCheckBox::stateChanged, [=](int state){ if(state == Qt::Checked) { textEdit->turnOnFullscreen(); } }); layout->addWidget(textEdit); layout->addWidget(dragText); layout->addWidget(checkBox); QWidget* window = new QWidget(this); window->setLayout(layout); setCentralWidget(window); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MMainWindow w; w.show(); return a.exec(); }
-
Hi and welcome to devnet,
Which version of Qt are you using ?
On which OS ?
Can you provide a complete minimal compilable example that shows that behaviour ? -
Hi
Is that this example?
https://doc.qt.io/qt-5/qtwidgets-draganddrop-puzzle-example.htmlI tried to make puzzleWidget fullscreen but it still worked.
-
I think, that problem connected with widget attributes:
Widget#ifndef WIDGET_H #define WIDGET_H #include <QWidget> class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); void turnOnFullscreen(); void dragEnterEvent(QDragEnterEvent *event) override; void dropEvent(QDropEvent *event) override; signals: }; #endif // WIDGET_H // ========================================================== #include "widget.h" #include <QApplication> #include <QWindow> #include <QDragEnterEvent> #include <QDropEvent> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent) { setAcceptDrops(true); setAttribute(Qt::WA_NativeWindow); // comment it, to fix problem setAttribute(Qt::WA_AcceptTouchEvents); setAutoFillBackground(false); setUpdatesEnabled(true); setFocusPolicy(Qt::StrongFocus); setMouseTracking(true); setTabletTracking(true); setMinimumSize(600, 600); setMaximumSize(600, 600); } void Widget::turnOnFullscreen() { if (!windowState().testFlag(Qt::WindowFullScreen)) { if (auto parent = parentWidget()) { setWindowIcon(parent->windowIcon()); } setParent(nullptr); const auto& screens = QApplication::screens(); const int screenNumber = 0; if (screenNumber >= 0 && screenNumber < screens.size()) { show(); windowHandle()->setScreen(screens[screenNumber]); } showFullScreen(); activateWindow(); raise(); setFocus(); } } void Widget::dragEnterEvent(QDragEnterEvent *event) { event->accept(); } void Widget::dropEvent(QDropEvent *event) { qInfo() << "Drop"; event->accept(); }
MainWindow:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); }; #endif // MAINWINDOW_H // ====================================== #include "mainwindow.h" #include "widget.h" #include <QCheckBox> #include <QVBoxLayout> #include <QFrame> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QFrame *frame = new QFrame; QVBoxLayout* layout = new QVBoxLayout(frame); Widget* widget = new Widget(); widget->setStyleSheet("background-color:white;"); QCheckBox* checkBox = new QCheckBox("fullscreen"); connect(checkBox, &QCheckBox::stateChanged, [=](int state){ if(state == Qt::Checked) { if(widget) { widget->turnOnFullscreen(); } } else { // ... } }); layout->addWidget(widget); layout->addWidget(checkBox); setCentralWidget(frame); } MainWindow::~MainWindow() { }
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
If comment line: setAttribute(Qt::WA_NativeWindow); that drag&drop correct work for other window, but documentation nothing say about it, i think it's bug. OS: windows, QT 15.14.2 MSVC 2017 x64
-
I think, that problem connected with widget attributes:
Widget#ifndef WIDGET_H #define WIDGET_H #include <QWidget> class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); void turnOnFullscreen(); void dragEnterEvent(QDragEnterEvent *event) override; void dropEvent(QDropEvent *event) override; signals: }; #endif // WIDGET_H // ========================================================== #include "widget.h" #include <QApplication> #include <QWindow> #include <QDragEnterEvent> #include <QDropEvent> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent) { setAcceptDrops(true); setAttribute(Qt::WA_NativeWindow); // comment it, to fix problem setAttribute(Qt::WA_AcceptTouchEvents); setAutoFillBackground(false); setUpdatesEnabled(true); setFocusPolicy(Qt::StrongFocus); setMouseTracking(true); setTabletTracking(true); setMinimumSize(600, 600); setMaximumSize(600, 600); } void Widget::turnOnFullscreen() { if (!windowState().testFlag(Qt::WindowFullScreen)) { if (auto parent = parentWidget()) { setWindowIcon(parent->windowIcon()); } setParent(nullptr); const auto& screens = QApplication::screens(); const int screenNumber = 0; if (screenNumber >= 0 && screenNumber < screens.size()) { show(); windowHandle()->setScreen(screens[screenNumber]); } showFullScreen(); activateWindow(); raise(); setFocus(); } } void Widget::dragEnterEvent(QDragEnterEvent *event) { event->accept(); } void Widget::dropEvent(QDropEvent *event) { qInfo() << "Drop"; event->accept(); }
MainWindow:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); }; #endif // MAINWINDOW_H // ====================================== #include "mainwindow.h" #include "widget.h" #include <QCheckBox> #include <QVBoxLayout> #include <QFrame> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QFrame *frame = new QFrame; QVBoxLayout* layout = new QVBoxLayout(frame); Widget* widget = new Widget(); widget->setStyleSheet("background-color:white;"); QCheckBox* checkBox = new QCheckBox("fullscreen"); connect(checkBox, &QCheckBox::stateChanged, [=](int state){ if(state == Qt::Checked) { if(widget) { widget->turnOnFullscreen(); } } else { // ... } }); layout->addWidget(widget); layout->addWidget(checkBox); setCentralWidget(frame); } MainWindow::~MainWindow() { }
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
If comment line: setAttribute(Qt::WA_NativeWindow); that drag&drop correct work for other window, but documentation nothing say about it, i think it's bug. OS: windows, QT 15.14.2 MSVC 2017 x64
Hi
I tried
puzzleWidget->setAttribute(Qt::WA_NativeWindow);
but it still worked.
This is Qt 5.14.2, window 10. vs2017 -
Hi
I tried
puzzleWidget->setAttribute(Qt::WA_NativeWindow);
but it still worked.
This is Qt 5.14.2, window 10. vs2017@mrjj Are you using this code to turn on fullscreen?
void PuzzleWidget::turnOnFullscreen() { if (!windowState().testFlag(Qt::WindowFullScreen)) { if (auto parent = parentWidget()) { setWindowIcon(parent->windowIcon()); } setParent(nullptr); const auto& screens = QApplication::screens(); const int screenNumber = 0; if (screenNumber >= 0 && screenNumber < screens.size()) { show(); windowHandle()->setScreen(screens[screenNumber]); } showFullScreen(); activateWindow(); raise(); setFocus(); } }
Now, i checked, that in my PC incorrect behavior is continues. You can run code (it's full), that i mentioned below
-
@mrjj Are you using this code to turn on fullscreen?
void PuzzleWidget::turnOnFullscreen() { if (!windowState().testFlag(Qt::WindowFullScreen)) { if (auto parent = parentWidget()) { setWindowIcon(parent->windowIcon()); } setParent(nullptr); const auto& screens = QApplication::screens(); const int screenNumber = 0; if (screenNumber >= 0 && screenNumber < screens.size()) { show(); windowHandle()->setScreen(screens[screenNumber]); } showFullScreen(); activateWindow(); raise(); setFocus(); } }
Now, i checked, that in my PC incorrect behavior is continues. You can run code (it's full), that i mentioned below
@magicDM
Well i just didMainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setupMenus(); setupWidgets(); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); setWindowTitle(tr("Puzzle")); puzzleWidget->setParent(nullptr); puzzleWidget->show(); puzzleWidget->showFullScreen(); puzzleWidget->activateWindow(); puzzleWidget->raise(); puzzleWidget->setFocus(); puzzleWidget->setAttribute(Qt::WA_NativeWindow); }
So it seems the same except the monitor handling but i only have one monitor so seems pretty much the same.
-
@magicDM
Well i just didMainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setupMenus(); setupWidgets(); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); setWindowTitle(tr("Puzzle")); puzzleWidget->setParent(nullptr); puzzleWidget->show(); puzzleWidget->showFullScreen(); puzzleWidget->activateWindow(); puzzleWidget->raise(); puzzleWidget->setFocus(); puzzleWidget->setAttribute(Qt::WA_NativeWindow); }
So it seems the same except the monitor handling but i only have one monitor so seems pretty much the same.
-
@mrjj
Ok tried yours turnOnFullscreen()
just for kick and still working.I go fullscreen from start. Do you start up in normal mode and then swap ?
-
@mrjj Yes, now i'm comment windowHandle()->setScreen(screens[screenNumber]); and drag and drop fine work, may be something wrong with it. I go in normal mode, and then via checkbox change state to fullscreen mode
-
@magicDM
Hi
If i wait and use the menu to call turnOnFullscreen then it stops working and shows
the red not accepted on whole form.@mrjj This code should simulate problem:
#include <QApplication> #include <QMainWindow> #include <QWidget> #include <QTextEdit> #include <QHBoxLayout> #include <QCheckBox> #include <QDebug> class Widget : public QTextEdit { public: Widget(QWidget* parent = nullptr) : QTextEdit(parent) { setAcceptDrops(true); setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_AcceptTouchEvents); setAutoFillBackground(false); setUpdatesEnabled(true); setFocusPolicy(Qt::StrongFocus); setMouseTracking(true); setTabletTracking(true); } void turnOnFullscreen() { if (!windowState().testFlag(Qt::WindowFullScreen)) { setParent(nullptr); show(); showFullScreen(); activateWindow(); raise(); setFocus(); } } }; class MMainWindow : public QMainWindow { public: MMainWindow(QWidget* parent = nullptr) : QMainWindow(parent) { QHBoxLayout* layout = new QHBoxLayout(this); Widget* textEdit = new Widget(this); QCheckBox* checkBox = new QCheckBox("Fullscreen mode", this); QTextEdit* dragText = new QTextEdit("Text for drag and drop", this); dragText->setReadOnly(true); connect(checkBox, &QCheckBox::stateChanged, [=](int state){ if(state == Qt::Checked) { textEdit->turnOnFullscreen(); } }); layout->addWidget(textEdit); layout->addWidget(dragText); layout->addWidget(checkBox); QWidget* window = new QWidget(this); window->setLayout(layout); setCentralWidget(window); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MMainWindow w; w.show(); return a.exec(); }
-
A bug reported: https://bugreports.qt.io/browse/QTBUG-85775