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

Setting Focus in floating QDockWidget



  • Hey, im having a issue with setting the focus to anewly created QDOckWidget thats floating.

    My basic process is that I create a QDockWidget and then try to give it focus. I've found that so if it is docked in the main window then it can receive focus however as soon as i call <setFloating(true)> it will no longer be allowed to get focus.

    Can anyone explain why this happens so I can understand this problem and if so how its possible to fix it.

    Heres the relevant code.

    // QDockWidget Constructer, called on the mouse press event
    DockPanel::DockPanel(QWidget *parent, QWidget * hold_widget, QString title, bool popup) :
    	QDockWidget(parent),
    	popup(popup)
    {
    	setObjectName(title);
    	setFeatures(QDockWidget::DockWidgetMovable);
    	DockPanelTitle * panel_title = new DockPanelTitle(this, title);
    
    	setTitleBarWidget(panel_title);
    	setWidget(hold_widget);
    
    	if (popup)
    	{
    		setFocusPolicy(Qt::StrongFocus);
    		setFloating(true); // it gives focus if this line is disabled but not if its active
    		setFocus();
    	}
    }
    
    // mousePressEevent, creates the new QDockWidget and adds it to the central window,
    // The bottom part simply loops through my dockwidgets and attempts to give them focus to see if it works,
    // the docked widgets recieve focus but the floating ones do not.
    void WindowToolBarButton::mousePressEvent(QMouseEvent * e)
    {
    	QMainWindow * cw = window()->findChild<QMainWindow *>("CentralWindow");
    	HolderWidget * widget_a = new HolderWidget(this);
    	QPoint m = window()->mapToGlobal(cw->pos());	
    
    	DockPanel * panel_a = new DockPanel(cw, widget_a, btn_label->text(), true);
    	panel_a->setGeometry(m.x(), m.y(), 300, cw->height());
    
    	cw->addDockWidget(Qt::RightDockWidgetArea, panel_a);
    
    	cw->setFocus();
    	QWidget * w = qApp->focusWidget();
    	for (DockPanel * child : w->findChildren<DockPanel *>())
    	{	
    		child->setFocus();
    		QString s = child->objectName();
    		std::cout << "Widget: " + s.toStdString() + " has focus " << child->hasFocus() << std::endl;
    	}
    }
    

    Any help would be appreciated as I dont really understand why this is happening, ive included everything I though would be useful but if something else is needed please let me know.

    Thanks for taking the time to look at my problem


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    What version of Qt are you using ?
    On what OS ?


  • Lifetime Qt Champion

    Hi
    I assume setFloating use an internal signal or likewise since you cannot setFocus right after. ( didnt not check source)

    Also, since its a window, activateWindow seems better since normally
    setFocus on a Dock would focus its internal widget.

    However, this works for me on Qt 5.12.6 win 10

        dw->setFloating(true);
        QTimer::singleShot(0, [dw]() {
         dw->activateWindow();
        });
    


  • Sorry for the late reply, I actually managed to figure out how to get my intended behaviour, after calling <setFloating(true)> i needed to add <setWindowFlags(Qt::Window | Qt::FramelessWindowHint);> to make it able to take focus.