2016-02-19 21 views
3

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

我知道QDekstopWidget具有屏幕功能()。这不是我想要的。当我想使用 显示ID直接访问X显示器时,I 有特殊情况。

让我知道是否有反正这样做。 更新:试过这种

#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

[email protected]:/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. 

回答

2

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

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

Here也是一些信息。

+0

这是否改变什么'XReparentWindow(显示器,w.winId(),x11root,0,0);'(在我看来,你并不需要创建第二个窗口)?如果这没有帮助,除了有两个独立的QApplications,我没有更多的想法,但是你可能需要两个进程。 – dmi

+0

是的,你的权利创建第二个窗口应该没有必要。它没有与根窗口一起工作,所以我只创建了第二个窗口来尝试。 –

1

如果你看一下QXcbConnection构造,m_displayName是,如果它不为空,或以其他方式DISPLAY环境变量初始化为displayName参数的内容,然后调用xcb_connect()与显示器,并且从那时起,该Qt应用程序通常只会与该显示进行对话。它不会自动发现其他显示。 QXcbConnection在QXcbIntegration的构造函数中创建,并在QGuiApplication的init_platform函数中创建。 QXcbIntegration也查找-display命令行参数,因此这是选择显示的第二种方法(覆盖DISPLAY env变量)。

配置它的第三种方式是由init_platform分离所有附加到平台插件名称的冒号分隔参数,最终作为QStringList参数传递给QXcbIntegration构造函数。 QXcbIntegration一次带两个并为每一对创建额外的QXcbConnection实例。因此,如果您使用-platform xcb::0.1::0.2启动应用程序,它将连接到除默认值(通常来自DISPLAY env变量)之外的显示:0.1和:0.2。如果您给出无效的显示,它会失败,并说“无法连接到显示:0.2”例如。

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

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

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

您也可以设置env变量QPA_PLATFORM而不是给出-platform参数。并且在你的主体中,如果你想避免需要在shell中配置env变量,你甚至可以使用qputenv来设置构建QApplication之前的env变量之前的。如果你弄清楚如何发现显示器,你可以通过编程来建立这个参数。

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

+0

感谢您的支持!我会试试看。你会在qt4中知道一个方法吗...我们的应用程序是在qt4中,所以我们必须为此升级到qt5。 –

+0

尝试了您的解决方案。请让我知道,如果我错过了什么 –

+0

尝试qscreen测试。让我知道你的想法 –

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(); 
} 

希望你有想法。尝试在我的机器上,它的工作。

谢谢。

+0

很容易在给定的显示器上显示整个应用程序。你也可以在命令行上输出DISPLAY =:2。我们想要的是一种编程方式...因此,例如,我们可以显示一个窗口:1和另一个显示:2在单个应用程序内。 –