【问题标题】:Is it possible to have a QWidget without a display?是否可以有一个没有显示器的 QWidget?
【发布时间】:2011-01-30 18:31:34
【问题描述】:

我有一个仅限控制台的 win32 应用程序(可以作为 Windows 服务启动),我想在其中创建 QWidget 对象并与之交互。

这些QWidget不会在本地渲染(因为没有显示),但我需要访问绘画操作(例如创建它们的截图),我需要拦截鼠标和键盘操作。

该服务的目的是向远程应用程序提供小部件的显示。因此,图像、鼠标和键盘应通过网络重定向。

是否可以在控制台应用程序中包含 QWidget 对象?在这种情况下,拦截绘画、鼠标和键盘操作的首选方法是什么?

如果可行,QAxWidget 对象是否仍然可行?

【问题讨论】:

  • 如果小部件没有显示在屏幕上的任何位置,键盘尤其是鼠标操作应该如何工作?
  • 该服务的目的是向远程应用程序提供小部件的显示。因此,图像、鼠标和键盘将通过网络重定向。注意:对于这种非常特殊的情况,我正在寻找现有远程显示协议(如 RDP)的替代方案。

标签: windows qt


【解决方案1】:

看看Qt for embedded Linux.。 Qt 的设计目的是让您可以做到这一点,但它并非微不足道。

不过,如果您的控制台模式服务需要键盘、鼠标和图形用户界面,我确实怀疑您没有走上正轨。与用户交互的需求告诉我它不应该是一项服务,而对鼠标的需求表明它也不应该是一个控制台应用程序。

【讨论】:

    【解决方案2】:

    您可以使用provided constructors 之一在没有 Gui 的情况下创建QApplication

    QApplication::QApplication(int&, char**, bool GuiEnabled)
    

    为了进行 GUI 操作,您仍然需要一个可用的 GUI。例如,在 Linux 上,它仍然需要 X 正在运行并且可用。我相信对可以发生和不能发生的事情有一定的限制,但在http://labs.qt.nokia.com 上找不到提供详细信息的博文。

    【讨论】:

    • 来自链接:“在 Windows 和 Mac OS 上,当前窗口系统总是被初始化,不管 GUIenabled 的值如何。这可能会在未来的 Qt 版本中改变。”
    【解决方案3】:

    目前我自己正在尝试做类似的事情。我采用的方法是创建 QGraphicsScene 的子类并覆盖 QGraphicsScene::sceneChanged 事件。然后如下(伪代码):

    QApplication app;
    MyGraphicsScene* mgs = new MyGraphicsScene();
    MyWidget* mw = new MyWidget();
    mgs->addWidget(mw);
    

    现在每次发生更改时都会调用您的 sceneChanged。在那里你可以得到场景的快照作为 QImage。在我的情况下,我将像素数据移动到纹理并将其渲染为我的游戏的覆盖:

    void QEOverlay::sceneChanged(QList<QRectF> list)
    {
        //loop through all screen areas that changed
        foreach(QRectF rect, list)
        {
            //generate a rectangle that is a while number, and fits withing the screen
            if(rect.x() < 0) rect.setX(0);
            if(rect.y() < 0) rect.setY(0);
            if(rect.right() > _width) rect.setRight(_width);
            if(rect.bottom() > _height) rect.setRight(_height);
            rect = QRectF(Round(rect.x()),Round(rect.y()),Round(rect.width()),Round(rect.height()));
    
            //Create an image, create a qpainter, fill the image with transparent color, and then render a part of the scene to it
            QImage image(rect.width(),rect.height(),QImage::Format_ARGB32);
            QPainter p(&image);
            image.fill(0);
            render(&p,image.rect(),rect);
    
            if(tex.lock())
            {
                for (u32 y = 0; y < image.height(); y++)
                {
                    for (u32 x = 0; x < image.width(); x++)
                    {
                        QRgb pix = image.pixel(x, y);
                        tex.color(x + rect.left(), y + rect.top(), Color(qRed(pix), qGreen(pix), qBlue(pix), qAlpha(pix)));
                    }
                }
                tex.unlock();
            }
        }
    }
    

    这种方法存在问题。您仍然需要将键盘和鼠标输入事件重定向到您的子类。这对我来说不是很好,有一些问题,比如鼠标点击没有聚焦 QLineEdit 或 QWebView 中的元素。

    【讨论】:

    • 这是一个有趣的解决方案,但根据文档,它不适用于 QAxWidget 对象...
    猜你喜欢
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-15
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多