Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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();
    }
    

  • Lifetime Qt Champion

    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 ?


  • Lifetime Qt Champion

    Hi
    Is that this example?
    https://doc.qt.io/qt-5/qtwidgets-draganddrop-puzzle-example.html

    I tried to make puzzleWidget fullscreen but it still worked.
    alt text



  • 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


  • Lifetime Qt Champion

    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


  • Lifetime Qt Champion

    @magicDM
    Well i just did

    MainWindow::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.


  • Lifetime Qt Champion

    @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


  • Lifetime Qt Champion

    @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();
    }
    
    



Log in to reply