фокус ввода клавиатуры на диалоге - как?
От: FF  
Дата: 21.07.12 09:59
Оценка:
Минимальный пример:

#include <QApplication>
#include <QTextStream>
#include <QMessageBox>

int main(int argv, char** args)
{
        QApplication app(argv, args);
        QTextStream input(stdin, QIODevice::ReadOnly);
        input.setCodec("UTF-8");

        for (;;)
        {
                QString str = input.readLine();
                if (str.isNull())
                        return 0;

                QMessageBox dialog;
                dialog.exec();
        }
        return 0;
}


$ cat | ./a.out
string1
string2
^C

После ввода string1 диалог активен и имеет фокус ввода (закрываем его)
После ввода string2 диалог неактивен и фокус ввода остаётся в терминале

$ echo -e "string1\nstring2" | ./a.out

Работает как требуется — фокус есть оба раза.

$ qmake --version
QMake version 2.01a
Using Qt version 4.7.0 in /usr/lib64/qt/lib
$ kde4-config --version
Qt: 4.7.0
KDE: 4.5.5 (KDE 4.5.5)
kde4-config: 1.0


На Qt 4.8.1 тоже самое.

В Windows (XP и 7):
$ cat | ./a.out
string1
string2
^C
[/code]
После ввода string1 диалог открывается на первом плане, но не получает фокус ввода клавиатуры (закрываем его)
После ввода string2 диалог активен, на переднем плане и имеет фокус ввода

$ echo -e "string1\nstring2" | ./a.out

Работает как требуется — фокус есть оба раза.


Под X11 модифицировал так (работает — фокус MessageBox получает всегда)
#include <QApplication>
#include <QTextStream>
#include <QMessageBox>
#include <QX11Info>

#ifdef Q_WS_X11
#include <X11/Xlib.h>
#elif defined(Q_OS_WIN)
#include <Windows.h>
#endif

void activateWindow(QWidget* w)
{
        w->show();
        w->raise();

#ifdef Q_WS_X11

        Display* dpy = QX11Info::display();

        XClientMessageEvent ev = { 0 };

        ev.type = ClientMessage;
        ev.window = w->winId();
        ev.message_type = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
        ev.format = 32;
        ev.send_event = True;
        ev.data.l[1] = QX11Info::appUserTime();

        XSendEvent(dpy, RootWindowOfScreen(DefaultScreenOfDisplay(dpy)), False,
                        SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&ev);
        XSync(dpy, False);

#elif defined(Q_OS_WIN)

        // TODO ???
        // SetForegroundWindow(w->winId());
        // SetWindowPos(w->winId(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

#endif

        w->activateWindow();
}

int main(int argv, char** args)
{
        QApplication app(argv, args);
        QTextStream input(stdin, QIODevice::ReadOnly);
        input.setCodec("UTF-8");

        for (;;)
        {
                QString str = input.readLine();
                if (str.isNull())
                        return 0;

                QMessageBox dialog;
                activateWindow(&dialog);
                dialog.exec();
        }
        return 0;
}


1) Как исправить в Windows (или не использовать платформозависимый код), чтобы фокус ввода клавиатуры был всегда на диалоге?
2) Не пояснит ли кто-нибудь почему работает "$ echo -e "string1\nstring2" | ./a.out" и не работает "$ cat | ./a.out"? Может быть что-то можно с потоком ввода сделать?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.