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

server/2024/10/16 2:31:09/

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/server/125606.html

相关文章

信息安全工程师(22)密码学网络安全应用

前言 密码学在网络安全中的应用极为广泛且深入&#xff0c;它通过多种技术手段确保数据的机密性、完整性和真实性。 一、数据加密 对称加密&#xff1a; 定义&#xff1a;使用相同的密钥进行加密和解密的过程。特点&#xff1a;加密和解密速度快&#xff0c;适用于大数据量的加…

安达发|纺织行业APS系统中的物料替代解决方案

在纺织行业中&#xff0c;物料替代是应对原材料短缺、成本波动和供应链不确定性的一种重要策略。高级计划与排程系统&#xff08;APS&#xff09;通过集成物料替代功能&#xff0c;可以帮助企业在保持生产效率的同时&#xff0c;灵活应对市场变化。本文将探讨纺织行业在APS系统…

麒麟桌面系统V10 SP1安装php的达梦数据库扩展

一、安装达梦数据库&#xff08;如果该web环境不安装&#xff0c;需要从已经安装的环境里拷贝驱动文件&#xff0c;注意系统架构和php版本的适配性&#xff09; 1. 参考https://eco.dameng.com/document/dm/zh-cn/start/install-dm-linux-prepare.html的步骤安装数据库 二、安…

linux远程桌面:xrdp 安装失败

window 如何远程 Linux 桌面 安装xrdp yum install xrdpsystemctl start xrdp 如果找不到软件包&#xff0c;就安装epel源&#xff0c;最好改成国内镜像的 在 /etc/yum.repos.d/ 下创建epel.repo,内容如下 [epel] nameExtra Packages for Enterprise Linux 7 - $basearch …

【笔记篇】Davinci Configurator OS模块(下)

文章目录 3 Vector OS特点3.1 优化的自旋锁3.1 核心同步3.1.1 描述3.1.2 启用3.1.3 使用3.2 屏障(Barriers)3.2.1 描述3.2.2 启用3.2.3 使用3.3 外设访问API3.3.1 描述3.3.2 启用3.3.3 使用3.3.4 依赖性3.3.5 替代方案3.3.6 常见使用案例3.4 可信函数的桩程序接口3.4.1 描述3…

双向链表的实现

前言 上节谈到单链表的实现&#xff0c;双向链表看似复杂&#xff0c;实际上只需套用单链表的实现&#xff0c;再让各个节点互相连 接即可&#xff0c;以下是具体实现与讲解。 相关接口如下&#xff1a; #pragma once #include <stdio.h> #include <stdlib.h> …

代码训练营 day17|LeetCode 235,LeetCode 701,LeetCode 450

前言 这里记录一下陈菜菜的刷题记录&#xff0c;主要应对25秋招、春招 个人背景 211CS本CUHK计算机相关硕&#xff0c;一年车企软件开发经验 代码能力&#xff1a;有待提高 常用语言&#xff1a;C 系列文章目录 第二十天 二叉树 part07 文章目录 前言系列文章目录第二十天 …

Visual Studio 2022

VS&#xff08;Visual Studio&#xff09;是一款由微软开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;用于开发应用程序、网站以及移动应用等。VS的历史可以追溯到1997年&#xff0c;当时发布了第一个版本的VS。以下是VS的一些重要历史里程碑&#xff1a; Visual …