【发布时间】:2014-06-09 08:24:25
【问题描述】:
是关于Windows下两个Qt程序的通讯。 一个程序,我们称他为客户端,另一个程序,称为服务器。 情况: 我想将客户端放在服务器的 QWidget 中。 Windows 已经提供了一些很好的方法来删除装饰(边框、标题栏等)并更改窗口的父级,因此重新绘制、调整大小、激活窗口都由 Windows 负责。 当我使用 QProcess 启动我的客户端时,我等待它启动,以便有一个可以与之交谈的窗口。然后我删除装饰并将服务器的 QWidget 设置为父级。 全部用这段代码完成:
winHandle = ::FindWindowA(NULL, "My Client");//get clients window id
if(winHandle != NULL)
{
::ShowWindow(winHandle, SW_HIDE);
// Remove the window border
LONG lStyle = GetWindowLong(winHandle, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
::SetWindowLong(winHandle, GWL_STYLE, lStyle);
::SetParent(winHandle, (HWND)(ui->widget->effectiveWinId()));//set the server's widget to be the parent of the client win
::SetWindowPos(winHandle, HWND_TOP, ui->widget->pos().x(), ui->widget->pos().y(), 0, 0 , SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOSIZE | SWP_ASYNCWINDOWPOS);
::UpdateWindow(winHandle);
::ShowWindow(winHandle, SW_SHOW);
}
这一切都很完美,我的客户很好地放在了我的标签上,所有的重绘等工作都很完美。 但是,我面临的问题是,有时(并非总是如此!)servers' 按钮没有响应。 我注意到当这种情况发生时,按钮不会响应只要它们位于屏幕中间。但是,最奇怪的是,如果我移动整个窗口,使按钮靠近屏幕边缘 - 它们可以工作!如果我将它移回中心 - 他们会再次停止工作。 任何的想法??有人吗?
我还尝试了以下代码:
QWindow * window = QWindow::fromWinId((WId) winHandle);
QWidget * widget = QWidget::createWindowContainer(window);
widget->setParent( ui->widget);
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(widget);
ui->widget->setLayout(layout);
使用此解决方案,GUI 不会冻结,但键盘现在无法在客户端窗口(内部窗口)中工作。 例如 - 如果内部窗口是记事本 - 我不能在里面输入,但我可以使用鼠标。 知道可以做什么吗?
【问题讨论】:
-
跨进程重新设置窗口永远不会结束。您不应该这样做。你几乎没有机会把这项工作做好。你会想找到一个不同的解决方案来解决你的问题。
-
你有什么建议吗?
-
在单个进程中运行整个 UI。
-
使用 Qt 你将没有机会让它工作。曾经。停止做你现在正在做的事情,不要落入它几乎已经起作用了的陷阱。虽然@David 已经提供了建议,但这还不够。如果您的 GUI 跨线程分布,您将在单个进程中遇到相同的问题。换句话说:使您的 GUI 成为单线程的。如果这不是一个选项,您可能需要评估将客户端实现为
CLSCTX_LOCAL_SERVERActiveX 控件,它可以在上下文之外运行。 -
@IInspectable 不够是有点苛刻。大量未列出且无法在评论中列出的要求。你也没有把它们都列出来。
标签: qt winapi qwidget setparent