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

Issue with Focus Defaulting to Floating QDockWidget



  • Hi All,

    I am running into an issue trying to set focus to a newly docked widget with an existing QDockWidget that is floating. The problem is that even after attempting to call setFocus() and raise() on the widget that was just docked, the focus still goes back to the floating widget.

    I have created a simple program that has a MainWindow with two QDockWidgets within it. Launching the program the QDockWidgets are already docked.

    Specific Steps
    Undock Both Widgets - Now both widgets are considered "floating"
    Click in one - Type in the text field
    Click in the other - Type in the text field
    Drag one of the widgets to the main window and dock it
    The Focus goes back to the floating widget. The cursor is blinking the text field and if I type without clicking anything it will type in the floating widget.

    I have tried various solutions for this , but I cannot seem to come up with a good way to set focus on the widget that was recently docked. Basically, what I am looking to do would be if I was just typing in the widget while it was floating, the focus would be on the same widget when docked and the cursor already in the text field. (As if I was simply switching between floating widgets)

    I have connected the QDockWidget Signal for Toplevelchange to attempt to raise() and setFocus() appropriately but this does not seem to do anything. Focus continues to default to the "floating" widget. I have also attempted to directly set focus on the QLineEdit within the docked widget, but still the existing floating widget has focus.

    QtVersion: 5.9.1
    OS: Red Hat Linux 7
    Compiler: gnat-17.2_x64

    Source Code:
    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    
    private slots:
        void onDockWidget1();
        void onDockWidget2();
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <iostream>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        connect(ui->dockWidget_1,SIGNAL(topLevelChanged(bool)),this,SLOT(onDockWidget1()));
        connect(ui->dockWidget_2,SIGNAL(topLevelChanged(bool)),this,SLOT(onDockWidget2()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::onDockWidget1(){
        std::cout << "DockWidget 1 Top Level Changed - Setting Focus\n";
        ui->dockWidget_1->raise();
        ui->dockWidget_1->setFocus();
    }
    void MainWindow::onDockWidget2(){
        std::cout << "DockWidget 2 Top Level Changed - Setting Focus\n";
        ui->dockWidget_2->raise();
        ui->dockWidget_2->setFocus();
    
    }
    

    mainwindow.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>386</width>
        <height>238</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <property name="layoutDirection">
       <enum>Qt::LeftToRight</enum>
      </property>
      <widget class="QWidget" name="centralWidget"/>
      <widget class="QMenuBar" name="menuBar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>386</width>
         <height>19</height>
        </rect>
       </property>
      </widget>
      <widget class="QToolBar" name="mainToolBar">
       <attribute name="toolBarArea">
        <enum>TopToolBarArea</enum>
       </attribute>
       <attribute name="toolBarBreak">
        <bool>false</bool>
       </attribute>
      </widget>
      <widget class="QStatusBar" name="statusBar"/>
      <widget class="QDockWidget" name="dockWidget_1">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="focusPolicy">
        <enum>Qt::NoFocus</enum>
       </property>
       <property name="floating">
        <bool>false</bool>
       </property>
       <property name="features">
        <set>QDockWidget::AllDockWidgetFeatures</set>
       </property>
       <attribute name="dockWidgetArea">
        <number>1</number>
       </attribute>
       <widget class="QWidget" name="dockWidgetContents_2">
        <layout class="QVBoxLayout" name="verticalLayout_2">
         <item>
          <layout class="QVBoxLayout" name="verticalLayout">
           <item>
            <widget class="QLineEdit" name="lineEdit"/>
           </item>
          </layout>
         </item>
        </layout>
       </widget>
      </widget>
      <widget class="QDockWidget" name="dockWidget_2">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <property name="focusPolicy">
        <enum>Qt::NoFocus</enum>
       </property>
       <attribute name="dockWidgetArea">
        <number>2</number>
       </attribute>
       <widget class="QWidget" name="dockWidgetContents_5">
        <layout class="QVBoxLayout" name="verticalLayout_6">
         <item>
          <layout class="QVBoxLayout" name="verticalLayout_5">
           <item>
            <widget class="QLineEdit" name="lineEdit_4"/>
           </item>
          </layout>
         </item>
        </layout>
       </widget>
      </widget>
     </widget>
     <layoutdefault spacing="6" margin="11"/>
     <resources/>
     <connections/>
    </ui>
    

    Any ideas for a solution to this?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Indeed code would be appreciated as it will allow people to reproduce your issue the same way you have.

    Additional points for:

    • Qt version
    • OS version
    • Compiler used


  • Found a solution for this.

    Using QWidget->ActivateWindow() on the widget that was just docked forces the widget to become the active "window" and puts the keyboard focus within that.

    https://doc.qt.io/qt-5/qwidget.html#activateWindow


Log in to reply