2016-02-19 16 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在單個應用程序內。 –