用systemd 来控制 qt 程序的启动, 停止 . 解决 qt.qpa.xcb: could not connect to display 问题

devtools/2024/10/16 2:30:14/

qt_%0A_qtqpaxcb_could_not_connect_to_display__1">author: hjjdebug
date: 2024年 09月 28日 星期六 15:49:51 CST
description: 用systemd 来控制 qt 程序的启动,停止
解决 qt.qpa.xcb: could not connect to display 问题

1. 先写一个QT 的测试程序 basic,

让他不断打印数字.

$ cat main.cpp 
#include <QApplication>
#include <QThread>
#include <QDebug>class MyThread: public QThread
{void run(){int count=0;while(1){qDebug()<<"running:"<<count++;sleep(1);}}
};
int main(int argc, char *argv[])
{QApplication app(argc,argv);MyThread thread;thread.start();return app.exec();
}
1.1: 运行,正常
$ ./basic
running: 0
running: 1
running: 2
running: 3

2. 再写这个程序的服务配置文件

$ cat basic.service 
[Unit]
Description=Basic Test[Service]
Type=simple
ExecStart=/home/hjj/test/qt//basic/basic
Restart=on-failure[Install]
WantedBy=multi-user.target

3. 测试: 启动服务失败:

$ sudo systemctl start basic.service

4. 状态查询

$ sudo systemctl status basic.service

● basic.service - Basic TestLoaded: loaded (/etc/systemd/system/basic.service; disabled; vendor preset: enabled)Active: failed (Result: core-dump) since Fri 2024-09-27 09:18:56 CST; 5s agoProcess: 6062 ExecStart=/home/hjj/test/qt//basic/basic (code=dumped, signal=ABRT)Main PID: 6062 (code=dumped, signal=ABRT)927 09:18:56 hjj-7090 systemd[1]: basic.service: Scheduled restart job, restart counter is at 5.
927 09:18:56 hjj-7090 systemd[1]: Stopped Basic Test.
927 09:18:56 hjj-7090 systemd[1]: basic.service: Start request repeated too quickly.
927 09:18:56 hjj-7090 systemd[1]: basic.service: Failed with result 'core-dump'.
927 09:18:56 hjj-7090 systemd[1]: Failed to start Basic Test.

5. 详细系统日志

$ journalctl -u basic.service

-- Logs begin at Thu 2024-07-25 08:51:30 CST, end at Fri 2024-09-27 09:26:52 CST. --
927 09:18:53 hjj-7090 systemd[1]: Started Basic Test.
927 09:18:53 hjj-7090 basic[6043]: qt.qpa.xcb: could not connect to display
927 09:18:53 hjj-7090 basic[6043]: qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
927 09:18:53 hjj-7090 basic[6043]: This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
927 09:18:53 hjj-7090 basic[6043]: Available platform plugins are: linuxfb, minimal, offscreen, vnc, xcb.
927 09:18:53 hjj-7090 systemd[1]: basic.service: Main process exited, code=dumped, status=6/ABRT
927 09:18:53 hjj-7090 systemd[1]: basic.service: Failed with result 'core-dump'.
927 09:18:54 hjj-7090 systemd[1]: basic.service: Scheduled restart job, restart counter is at 1.
927 09:18:54 hjj-7090 systemd[1]: Stopped Basic Test.
927 09:18:54 hjj-7090 systemd[1]: Started Basic Test.
927 09:18:54 hjj-7090 basic[6054]: qt.qpa.xcb: could not connect to display
927 09:18:54 hjj-7090 basic[6054]: qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
927 09:18:54 hjj-7090 basic[6054]: This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
927 09:18:54 hjj-7090 basic[6054]: Available platform plugins are: linuxfb, minimal, offscreen, vnc, xcb.
927 09:18:54 hjj-7090 systemd[1]: basic.service: Main process exited, code=dumped, status=6/ABRT
927 09:18:54 hjj-7090 systemd[1]: basic.service: Failed with result 'core-dump'.
927 09:18:54 hjj-7090 systemd[1]: basic.service: Scheduled restart job, restart counter is at 2.
927 09:18:54 hjj-7090 systemd[1]: Stopped Basic Test.
927 09:18:54 hjj-7090 systemd[1]: Started Basic Test.
927 09:18:54 hjj-7090 basic[6057]: qt.qpa.xcb: could not connect to display
927 09:18:54 hjj-7090 basic[6057]: qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
927 09:18:54 hjj-7090 basic[6057]: This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
927 09:18:54 hjj-7090 basic[6057]: Available platform plugins are: linuxfb, minimal, offscreen, vnc, xcb.
927 09:18:54 hjj-7090 systemd[1]: basic.service: Main process exited, code=dumped, status=6/ABRT
927 09:18:54 hjj-7090 systemd[1]: basic.service: Failed with result 'core-dump'.
927 09:18:55 hjj-7090 systemd[1]: basic.service: Scheduled restart job, restart counter is at 3.
927 09:18:55 hjj-7090 systemd[1]: Stopped Basic Test.
927 09:18:55 hjj-7090 systemd[1]: Started Basic Test.
927 09:18:55 hjj-7090 basic[6059]: qt.qpa.xcb: could not connect to display
927 09:18:55 hjj-7090 basic[6059]: qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
927 09:18:55 hjj-7090 basic[6059]: This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
927 09:18:55 hjj-7090 basic[6059]: Available platform plugins are: linuxfb, minimal, offscreen, vnc, xcb.
927 09:18:55 hjj-7090 systemd[1]: basic.service: Main process exited, code=dumped, status=6/ABRT
927 09:18:55 hjj-7090 systemd[1]: basic.service: Failed with result 'core-dump'.
927 09:18:55 hjj-7090 systemd[1]: basic.service: Scheduled restart job, restart counter is at 4.
927 09:18:55 hjj-7090 systemd[1]: Stopped Basic Test.
927 09:18:55 hjj-7090 systemd[1]: Started Basic Test.
927 09:18:55 hjj-7090 basic[6062]: qt.qpa.xcb: could not connect to display
927 09:18:55 hjj-7090 basic[6062]: qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
927 09:18:55 hjj-7090 basic[6062]: This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
927 09:18:55 hjj-7090 basic[6062]: Available platform plugins are: linuxfb, minimal, offscreen, vnc, xcb.
927 09:18:55 hjj-7090 systemd[1]: basic.service: Main process exited, code=dumped, status=6/ABRT
927 09:18:55 hjj-7090 systemd[1]: basic.service: Failed with result 'core-dump'.
927 09:18:56 hjj-7090 systemd[1]: basic.service: Scheduled restart job, restart counter is at 5.
927 09:18:56 hjj-7090 systemd[1]: Stopped Basic Test.
927 09:18:56 hjj-7090 systemd[1]: basic.service: Start request repeated too quickly.
927 09:18:56 hjj-7090 systemd[1]: basic.service: Failed with result 'core-dump'.
927 09:18:56 hjj-7090 systemd[1]: Failed to start Basic Test.

6. 错误原因: 环境变量不同所致!

systemd 的环境变量,只有区区17行

$ cat env.log
LANGUAGE=zh_CN
LC_ADDRESS=en_US.UTF-8
LC_NAME=en_US.UTF-8
LC_MONETARY=en_US.UTF-8
PWD=/
LC_PAPER=en_US.UTF-8
LANG=zh_CN.UTF-8
INVOCATION_ID=049b2226a6d74f39a2fb88aa82227756
LC_IDENTIFICATION=en_US.UTF-8
SHLVL=1
LC_TELEPHONE=en_US.UTF-8
LC_MEASUREMENT=en_US.UTF-8
LC_TIME=en_US.UTF-8
JOURNAL_STREAM=8:92364
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
LC_NUMERIC=en_US.UTF-8
_=/usr/bin/env

而我自己command 的环境变量有61行之多.
经过洗礼才有印象, 最后经过反复测试,比较得到2个关键环境变量.

DISPLAY:=0
XAUTHORITY=/run/user/1000/gdm/Xauthority

7. 命令行下复现问题.

你可以如下测试一下.
$ unset DISPLAY
hjj@hjj-7090:~/test/qt/basic$ ./basic
qt.qpa.xcb: could not connect to display
qt.qpa.plugin: Could not load the Qt platform plugin “xcb” in “” even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: linuxfb, minimal, offscreen, vnc, xcb.

已放弃 (核心已转储)

8. 错误到底是在什么地方出现的?

错误出处,原来在QApplication app(argc,argv)中有大量的函数调用,而且大量访问环境变量getenv(),
而其中DISPLAY,XAUTHORITY 环境变量是不可缺少的!!
否则就会在下面函数中打印出错信息!!

QApplicationPrivate::createEventDispatcher
"+>in init_platform of kernel/qguiapplication.cpp:1200                                               
21 in QGuiApplicationPrivate::createPlatformIntegration of ../../include/QtCore/../../src/corelib/te
32 in QGuiApplicationPrivate::createEventDispatcher of kernel/qguiapplication.cpp:1472              
43 in QApplicationPrivate::createEventDispatcher of kernel/qapplication.cpp:188                    
54 in QCoreApplicationPrivate::init of kernel/qcoreapplication.cpp:865                            
65 in QGuiApplicationPrivate::init of kernel/qguiapplication.cpp:1501                            
76 in QApplicationPrivate::init of kernel/qapplication.cpp:546                                  
87 in QApplication::QApplication of kernel/qapplication.cpp:534                                
98 in main of main.cpp:19                                                                     

调试挺不爽的,可能是有-O2 优化吧,算了,不调试了!

9. 解决办法: 补足其所需要的环境变量.

具体实现办法有两种,
一种是: 让服务程序去调用脚本. 脚本内容是先设置环境变量,再调用执行程序.
另一种: 让服务程序先设置环境变量,再调用程序.

我这里给出第一种吧,

$ cat basic.sh 
#!/bin/bash
export XAUTHORITY=/run/user/1000/gdm/Xauthority
export DISPLAY=:0
/home/hjj/test/qt/basic/basic &$ cat basic.service 
[Unit]
Description=Basic Test[Service]
Type=forking
#EnvironmentFile=/home/hjj/test/qt/basic/basic.env
ExecStart=/home/hjj/test/qt/basic/basic.sh
Restart=on-failure[Install]
WantedBy=multi-user.target


第二种就是把环境变量写到一个文件中例如 basic.env

$ cat basic.env
XAUTHORITY=/run/user/1000/gdm/Xauthority
DISPLAY=:0

并在上述服务配置中打开basic.env , 则basic.sh 中可不用导出环境变量
不管背着还是抱着,都是要把环境变量配上.

10. 最后的结果

$ sudo systemctl status basic.service

● basic.service - Basic TestLoaded: loaded (/etc/systemd/system/basic.service; disabled; vendor preset: enabled)Active: active (running) since Sat 2024-09-28 14:59:52 CST; 1h 1min agoProcess: 109495 ExecStart=/home/hjj/test/qt/basic/basic.sh (code=exited, status=0/SUCCESS)Main PID: 109498 (basic)Tasks: 3 (limit: 9097)Memory: 2.1MCGroup: /system.slice/basic.service└─109498 /home/hjj/test/qt/basic/basic928 16:01:31 hjj-7090 basic.sh[109498]: running: 3698
928 16:01:32 hjj-7090 basic.sh[109498]: running: 3699
928 16:01:33 hjj-7090 basic.sh[109498]: running: 3700
928 16:01:34 hjj-7090 basic.sh[109498]: running: 3701
928 16:01:35 hjj-7090 basic.sh[109498]: running: 3702

http://www.ppmy.cn/devtools/120044.html

相关文章

Python对数据库(MySQL,redis、MongoDB)的操作

Python对数据库的操作(MySQL,redis、MongoDB) 一、操作MySQL数据库 安装pymysql: 需要通过pip install pymysql进行安装。 查询数据:fetchone、fetchmany(n)、fetchall() import pymysql #建立mysql连接,ip、端口、用户名、密码(passwd,不能写成其他,例如:pwd或者p…

SSH 安全实战:保护您的远程访问

在当今的数字时代,远程访问已成为 IT 基础设施中不可或缺的一部分。SSH(Secure Shell)因其强大的加密和认证机制而成为首选的远程访问协议。本文将深入探讨如何通过一系列实用的步骤和最佳实践来加强 SSH 的安全性,确保您的远程访问既方便又安全。 SSH 基础知识回顾 SSH …

计算机视觉学习---图像增强

以下是一个简要的学习路线图&#xff1a; 图像增强学习路线 基础知识 数字图像基础色彩空间&#xff08;RGB、HSV等&#xff09;图像矩阵及其表示 基本技术 直方图均衡化 案例&#xff1a;对比度增强Gamma校正 案例&#xff1a;非线性亮度调整伽马变换 案例&#xff1a;低亮度…

【四】Spring Cloud OpenFeign原理分析

Spring Cloud OpenFeign原理分析 概述 Spring Cloud 微服务实践也有挺多年了&#xff0c;一直想着总结一下这系列的知识点&#xff0c;最近终于下定决心来出一个Spring Cloud 系列文章了。本文主要围绕fegin组件来进行讲解&#xff0c;文中将会给出基础使用的示例&#xff0c;还…

Mybatis-Plus新花样(二)

多种插件 Mybatis-plus给我们提供了各种各样的插件&#xff0c;方便我们快捷开发。 一. 插件配置 Configuration public class MybatisPlusConfig {Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInter…

C语言系列4——指针与数组(1)

我们开始C语言的指针与数组 这部分开始进阶了&#xff0c;得反复学习 在开始正题之前&#xff0c;写说一下我们都知道当写一个函数的时候需要进行传参&#xff0c;当实参传递给形参的时候&#xff0c;形参是有独立空间的&#xff0c;那么数组传参又是怎么样的呢&#xff0c;我…

0x09 瑞友 应用虚拟化系统 GetBSAppUrl SQL注入漏洞 - 复现

参考:瑞友 应用虚拟化系统 GetBSAppUrl SQL注入漏洞 | PeiQi文库 (wgpsec.org) 免责声明 欢迎访问我的博客。以下内容仅供教育和信息用途: 合法性:我不支持或鼓励非法活动。请确保遵守法律法规。信息准确性:尽管我尽力提供准确的信息,但不保证其完全准确或适用。使用前请…

Unity3D 房间去重叠化算法详解

前言 在Unity3D游戏开发中&#xff0c;经常需要生成和处理多个房间的场景&#xff0c;特别是在地牢生成、房屋布局或迷宫设计等应用中。为了确保生成的房间不会重叠&#xff0c;我们需要一种有效的去重叠化算法。以下将详细介绍该算法的原理和代码实现。 对惹&#xff0c;这里有…