我有一个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.
答案 0 :(得分:2)
答案 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();
}
希望你明白了。在我的机器上试过它,它运作良好。
感谢。