用于X显示的QDesktopWidget

时间:2016-02-19 06:41:35

标签: c++ linux qt xserver

我有一个X显示器说:2。我想在给定的X上显示我的qt小部件 显示。该显示与主显示不同。所以除了主显示器(由环境变量DISPLAY设置)之外,我还想访问一个额外的X显示器。

我知道QDekstopWidget有屏幕功能()。这不是我想要的。一世 当我想使用直接访问X Display时有一个特例 显示ID。

让我知道是否还有这样做。 更新:试过这个

#include<QApplication>
#include<QWidget>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>


int main(int argc, char *argv[])
{
QApplication a(argc, argv);

Display* display = XOpenDisplay(":1");

XSynchronize(display, True);
//XSetErrorHandler(myErrorHandler);

Window x11root = XDefaultRootWindow(display);

int x = 0;
int y = 0;
unsigned int width = 500;
unsigned int height = 500;
unsigned int borderWidth = 0;
long colorBlue = 0xff0000ff;

Window x11w = XCreateSimpleWindow(display, x11root, x, y, 
    width, height, borderWidth, 1 /*magic number*/, colorBlue);
XMapWindow(display, x11w); // must be performed after XReparentWindow, 
                           // otherwise the window is not visible.

QWidget w;
w.resize(200,200);
w.show();

XReparentWindow(display, w.winId(), x11w, 0, 0);

return a.exec();

}

按照建议尝试qscreen测试。它检测显示器,但两个窗口都在显示:3

shiva@RSV-HP-ENVY-15-Notebook-PC:/tmp/korvins-qtbase-6226fcdc3e4ace4636c58778ef53fbf69f46c36e-6226fcdc3e4ace4636c58778ef53fbf69f46c36e/tests/manual/qscreen$ ./qscreen -platform xcb::3::5
qt.core.logging: Loading "/home/shiva/.config/QtProject/qtlogging.ini" ...
qt.qpa.screen: Output VGA-1-0 is not connected
qt.qpa.screen: Output HDMI-1-0 is not connected
qt.qpa.screen: adding QXcbScreen(0x1b82f60, name="eDP-1-0", geometry=1366x768+0+0, availableGeometry=1309x744+57+24, devicePixelRatio=1.0, logicalDpi=QPair(96.0,96.0), physicalSize=344.0x194.0mm, screenNumber=0, virtualSize=1366x768 (1366.0x768.0mm), orientation=Qt::ScreenOrientation(LandscapeOrientation), depth=24, refreshRate=59.0, root=2c1, windowManagerName="Compiz") (Primary: true )
qt.qpa.screen: primary output is "eDP-1-0"
qt.qpa.screen: connecting to additional display: "" "3"
qt.qpa.screen: adding QXcbScreen(0x1bae540, name="TurboVNC", geometry=1024x716+0+0, availableGeometry=1024x664+0+28, devicePixelRatio=1.0, logicalDpi=QPair(96.0,96.0), physicalSize=271.0x189.0mm, screenNumber=0, virtualSize=1024x716 (1024.0x716.0mm), orientation=Qt::ScreenOrientation(LandscapeOrientation), depth=24, refreshRate=60.0, root=6a, windowManagerName="Metacity") (Primary: true )
qt.qpa.screen: primary output is "TurboVNC"
qt.qpa.screen: connecting to additional display: "" "5"
qt.qpa.screen: adding QXcbScreen(0x1bd6ca0, name="TurboVNC", geometry=1024x716+0+0, availableGeometry=1024x664+0+28, devicePixelRatio=1.0, logicalDpi=QPair(96.0,96.0), physicalSize=271.0x189.0mm, screenNumber=0, virtualSize=1024x716 (1024.0x716.0mm), orientation=Qt::ScreenOrientation(LandscapeOrientation), depth=24, refreshRate=60.0, root=6a, windowManagerName="Metacity") (Primary: true ) 
qt.qpa.screen: primary output is "TurboVNC"
Xlib: extension "GLX" missing on display ":5".
Xlib: extension "GLX" missing on display ":5".
Xlib: extension "GLX" missing on display ":5".
Xlib: extension "GLX" missing on display ":5".
Could not initialize OpenGL for RasterGLSurface, reverting to RasterSurface.
Xlib: extension "GLX" missing on display ":5".
Xlib: extension "GLX" missing on display ":5".
Xlib: extension "GLX" missing on display ":5".
Xlib: extension "GLX" missing on display ":5".
Could not initialize OpenGL for RasterGLSurface, reverting to RasterSurface.
Xlib: extension "GLX" missing on display ":5".
Xlib: extension "GLX" missing on display ":5".
Xlib: extension "GLX" missing on display ":5".
Xlib: extension "GLX" missing on display ":5".
Could not initialize OpenGL for RasterGLSurface, reverting to RasterSurface. 

3 个答案:

答案 0 :(得分:2)

QX11Info可以访问X显示信息。参考:QX11Info::display()

我假设您需要打开与第二个显示器的第二个X连接,并将其传递给新创建的小部件。

Here也是一些信息。

答案 1 :(得分:1)

如果查看QXcbConnection构造函数,m_displayName初始化为displayName参数的内容(如果它不为null),或者DISPLAY env变量,则调用xcb_connect() 1}}使用该显示,从那时起,该Qt应用程序通常只与该显示器对话。它不会自动发现其他显示。 QXcbConnection是在QXcbIntegration的构造函数中创建的,而后者又是在QGuiApplication的init_platform函数中创建的。 QXcbIntegration也会查找-display命令行参数,这是选择显示的第二种方式(覆盖DISPLAY env变量)。

配置它的第三种方法是由init_platform拆分任何冒号分隔的参数,这些参数附加到平台插件名称,最后作为QStringList参数传递给QXcbIntegration构造函数。 QXcbIntegration一次获取两个,并为每对创建额外的QXcbConnection实例。因此,如果您使用-platform xcb::0.1::0.2启动应用程序,它将连接到显示:0.1和:0.2以及默认值(通常来自DISPLAY env变量)。如果您提供无效显示,它将失败,并说&#34;无法连接到显示:0.2&#34;例如。

现在尝试使用QScreen手动测试(假设您有显示:0和:0.1可用):

cd path/to/qtbase/tests/manual/qscreen
qmake
make
./qscreen -platform xcb::0.1

您将在每个显示的每个输出上获得一个窗口,而没有任何参数,您将只在默认显示的每个输出上获得一个窗口。

您还可以设置env变量QPA_PLATFORM,而不是提供-platform参数。在您的主要内容中,您甚至可以使用qputenv在构建QApplication之前设置env变量 ,以防您需要在shell中配置env变量。如果您弄清楚如何发现显示,您可以通过编程方式构建该参数。

正如您在手动测试的main.cpp中所看到的,QGuiApplication::screens()将为Qt所连接的每个显示器上的每个输出提供一个QScreen实例。然后,您可以使用QScreen:name()或其他属性来标识要使用的屏幕。一个显示器上的多个输出通常并排排列,因此调用setGeometry()来定位窗口通常足以将其放在一个屏幕或另一个屏幕上;但在您的情况下,您有多个显示器,因此您还需要调用QWindow::setScreen() 将小部件的父级设置为相应的QDesktopWidget屏幕小部件,就像您一样可以在screenAdded()函数的中间看到。

答案 2 :(得分:0)

如果我理解你的问题,那么我会有一个讨厌的解决方案。 您可以通过指定./app -display:2手动设置显示 如果您不能这样做,您可以在main()函数中更改命令行选项。这样的事情。

#include <QApplication>
#include <QWidget>
#include <cstdio>
#include <cstring>

int main(int argc, char** argv)
{
    char** args = (char**)malloc((argc + 2) * sizeof(char*));
    for(int i = 0; i < argc; ++i) {
            int l = strlen(argv[i]);
            args[i] = (char*)malloc(l * sizeof(char));
            strcpy(args[i], argv[i]);
    }
    const char* const display = "-display_";
    const char* const display_number = ":2_";
    args[argc] = (char*)malloc(strlen(display) * sizeof(char));
    args[argc + 1] = (char*)malloc(strlen(display_number) * sizeof(char));
    strcpy(args[argc], display);
    strcpy(args[argc + 1], display_number);
    args[argc][strlen(display) - 1] = 0;
    args[argc + 1][strlen(display_number) - 1] = 0;
    for(int i = 0; i < argc + 2; ++i) {
            printf("%s\t%d\n", args[i], strlen(args[i]));
    }
    int aargc = argc + 2;
    QApplication app(aargc, args);
    QWidget w;
    w.show();
    return app.exec();
}

希望你明白了。在我的机器上试过它,它运作良好。

感谢。