Минимальный пример:
#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"? Может быть что-то можно с потоком ввода сделать?