Jan Synáček
Jan Synáček

Reputation: 355

How to automatically focus QDialog with a Qt.Popup flag set?

Consider the following code snippet using Python 3 and PyQt 5.5:

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

import sys

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = QWidget()
    d = QDialog()
    l = QLineEdit(d)
    w.show()
    # Comment the following line to gain focus.
    d.setWindowFlags(Qt.Popup)
    d.show()
    app.exec_()

After d.show() is invoked, the dialog is shown but the QLineEdit inside it doesn't have focus. No amount of raise_(), activateWindow() or setFocus() seems to be working. How can I make the dialog automatically gain focus when it's shown? I would like to keep the dialog as Qt.Popup, because I need it to close when I click outside of it.

Upvotes: 1

Views: 3437

Answers (2)

ekhumoro
ekhumoro

Reputation: 120718

It seems that you need to set focus on the line-edit after the dialog is shown:

    l = QLineEdit(d)
    w.show()
    d.setWindowFlags(Qt.Popup)
    d.show()
    l.setFocus()
    app.exec_()

If that doesn't work, try it with a timer:

    QTimer.singleShot(1, l.setFocus)

Upvotes: 0

Sebastian Lange
Sebastian Lange

Reputation: 4029

There is

QWidget::raise();
QWidget::activateWindow();

From the docs: Sets the top-level widget containing this widget to be the active window.

An active window is a visible top-level window that has the keyboard input focus.

This function performs the same operation as clicking the mouse on the title bar of a top-level window. On X11, the result depends on the Window Manager. If you want to ensure that the window is stacked on top as well you should also call raise(). Note that the window must be visible, otherwise activateWindow() has no effect.

On Windows, if you are calling this when the application is not currently the active one then it will not make it the active window. It will change the color of the taskbar entry to indicate that the window has changed in some way. This is because Microsoft does not allow an application to interrupt what the user is currently doing in another application.

Upvotes: 3

Related Questions