桌面环境 top bar上怎么显示中文?

系统字体配置、中文显示和输入法问题
回复
weijh006
帖子: 3
注册时间: 2021-07-28 11:53
系统: ubuntu18.04

请问运行软件时桌面top bar上怎样才能显示中文?

#1

帖子 weijh006 » 2021-07-28 14:09

在ubuntu18.04他ubuntu 20.04上,已经安装中文环境,可以正常显示中文。
运行Qt编写软件,在程序中调用 qApp->setApplicationName("Abc"), top bar上显示的是Abc。
如果调用 qApp->setApplicationName("汉字"), top bar上显示的就是乱码。请问要怎么设置,top bar 上才能正常显示中文?
weijh006
帖子: 3
注册时间: 2021-07-28 11:53
系统: ubuntu18.04

桌面环境 top bar上怎么显示中文?

#2

帖子 weijh006 » 2021-07-28 15:55

当前环境: ubuntu18.04 和 ubuntu 20.04, 已安装中文环境, 并且第三方软件运行时,桌面顶部的 top bar上可以显示中文名称。
现在是自己用QT写的程序,在源码中调用 qApp->setApplicationName 设置英文名称,可以正常显示。
如果设置的是中文,显示的就是乱码。UI上的中文显示是正常的,不知道top bar为什么会乱码。
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 桌面环境 top bar上怎么显示中文?

#3

帖子 astolia » 2021-08-02 11:27

一般是你自己没弄清楚在Qt中怎么处理编码。首先确保你源文件用的是utf-8编码。然后用QString::fromUtf8("中文内容")或者Qt5+的QStringLiteral("中文内容")来生成QString对象,而不要直接用字符串字面量"中文内容"
weijh006
帖子: 3
注册时间: 2021-07-28 11:53
系统: ubuntu18.04

Re: 桌面环境 top bar上怎么显示中文?

#4

帖子 weijh006 » 2021-08-03 9:37

QT中已想转码了, UI 上的 btn、label显示的中文都是对的,就是top bar 上一直是乱码。QString::fromUtf8,包括生成.qm 文件这种也试过,不起作用。
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 桌面环境 top bar上怎么显示中文?

#5

帖子 astolia » 2021-08-03 10:21

把你的代码文件上传上来
xxxiao
帖子: 3
注册时间: 2021-09-09 16:28

Re: 桌面环境 top bar上怎么显示中文?

#6

帖子 xxxiao » 2021-09-09 16:31

#pragma execution_character_set("utf-8")
#include "mainwindow.h"
#include <QApplication>
#include <QTextCodec>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
#if _MSC_VER
QTextCodec *codec = QTextCodec::codecForName("gbk");
#else
QTextCodec *codec = QTextCodec::codecForName("utf-8");
#endif
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
#else
QTextCodec *codec = QTextCodec::codecForName("utf-8");
QTextCodec::setCodecForLocale(codec);
#endif


a.setApplicationName(QStringLiteral("调试"));
MainWindow w;
w.setWindowTitle("调试");
w.show();
return a.exec();
}
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 桌面环境 top bar上怎么显示中文?

#7

帖子 astolia » 2021-09-10 11:14

xxxiao 写了: 2021-09-09 16:31 w.setWindowTitle("调试");
你这里还是用的是字符串字面量。我看你这里有针对qt5之前的兼容代码,根据文档 https://doc.qt.io/archives/qt-4.8/qstri ... #QString-8 在qt4你这行等价于w.setWindowTitle(QString::fromAscii("调试")),这样会转换出错的。
xxxiao 写了: 2021-09-09 16:31 a.setApplicationName(QStringLiteral("调试"));
这样用QStringLiteral在msvc上记得也会有些问题?以前在qt的bugreport上看到的方案是用c++11的QStringLiteral(u"调试")

我个人对linux/windows+qt4/5/6+gcc/mingw/msvc环境下处理字符串的经验是,首先保证代码源文件是utf-8,并启用c++11支持
然后定义这么一个_QStringLiteral宏

代码: 全选

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#define _QStringLiteral(str) QStringLiteral(u"" str "")
#else
#define _QStringLiteral(str) QString::fromUtf8("" str "", sizeof(str) - 1)
#endif
以后用需要用字符串字面量时就 _QStringLiteral("xxxxx")。对msvc再加上个编译参数/utf-8
xxxiao
帖子: 3
注册时间: 2021-09-09 16:28

Re: 桌面环境 top bar上怎么显示中文?

#8

帖子 xxxiao » 2021-12-31 15:01

astolia 写了: 2021-09-10 11:14
xxxiao 写了: 2021-09-09 16:31 w.setWindowTitle("调试");
你这里还是用的是字符串字面量。我看你这里有针对qt5之前的兼容代码,根据文档 https://doc.qt.io/archives/qt-4.8/qstri ... #QString-8 在qt4你这行等价于w.setWindowTitle(QString::fromAscii("调试")),这样会转换出错的。
xxxiao 写了: 2021-09-09 16:31 a.setApplicationName(QStringLiteral("调试"));
这样用QStringLiteral在msvc上记得也会有些问题?以前在qt的bugreport上看到的方案是用c++11的QStringLiteral(u"调试")

我个人对linux/windows+qt4/5/6+gcc/mingw/msvc环境下处理字符串的经验是,首先保证代码源文件是utf-8,并启用c++11支持
然后定义这么一个_QStringLiteral宏

代码: 全选

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#define _QStringLiteral(str) QStringLiteral(u"" str "")
#else
#define _QStringLiteral(str) QString::fromUtf8("" str "", sizeof(str) - 1)
#endif
以后用需要用字符串字面量时就 _QStringLiteral("xxxxx")。对msvc再加上个编译参数/utf-8
感谢帮助,但使用您上面提供的方法修改后,topbar任然是乱码。。。可以提供一个测试运行成功的demo吗 :Haha
xxxiao
帖子: 3
注册时间: 2021-09-09 16:28

Re: 桌面环境 top bar上怎么显示中文?

#9

帖子 xxxiao » 2021-12-31 15:05

#pragma execution_character_set("utf-8")
#include <QMainWindow>
#include <QApplication>
#include <QTextCodec>

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#define _QStringLiteral(str) QStringLiteral(u"" str "")
#else
#define _QStringLiteral(str) QString::fromUtf8("" str "", sizeof(str) - 1)
#endif

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
#if _MSC_VER
QTextCodec *codec = QTextCodec::codecForName("gbk");
#else
QTextCodec *codec = QTextCodec::codecForName("utf-8");
#endif
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
#else
QTextCodec *codec = QTextCodec::codecForName("utf-8");
QTextCodec::setCodecForLocale(codec);
#endif

a.setApplicationName(_QStringLiteral("调试"));
QMainWindow w;
w.setWindowTitle(_QStringLiteral("调试"));
w.show();

return a.exec();
}

感谢帮助,但改成这样仍然是乱码,可以提供一个测试通过的demo吗
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 桌面环境 top bar上怎么显示中文?

#10

帖子 astolia » 2021-12-31 23:10

我研究了一下,显示乱码的根本原因是这样的:

gnome桌面环境,对于某个程序在top bar中显示的名称,首先是查找有没有对应的启动器(.desktop)文件,有的话就用启动器中规定的名称,否则对x11程序用WM_CLASS属性中的名称,wayland程序用进程名。

QApplication::setApplicationName这句在x11环境中的作用就是设置WM_CLASS属性。但是,WM_CLASS属性的文本编码只支持latin-1,所以即使设置的是一个utf8字串,gnome仍然会当成latin-1编码去解析,就造成了乱码。

wayland下面又是另外的逻辑。你可以自己试一下,注销当前用户,选择用户名后在右下角齿轮处选wayland会话选项,再登录进去就是wayland环境。如果你还没有安装qtwayland5包先安装一下。然后用

代码: 全选

QT_QPA_PLATFORM=wayland /path/to/your/program
或者

代码: 全选

/path/to/your/program -platform wayland
来以wayland程序方式运行你的程序。这时top bar上显示的就是可执行文件名,跟setApplicationName设置的无关了。如果可执行文件名是中文的,top bar上的也是中文。

所以如果想要保证在gnone桌面上无论哪种环境都显示中文,最好还是走启动器方案。具体方法如下,在系统全局的/usr/share/applications或者仅当前用户的~/.local/share/applications下面创建一个启动器文件。如果你的可执行程序叫abc,文件就叫abc.desktop,基本内容如下

代码: 全选

[Desktop Entry]
Version=1.0
Name=中文名称
Exec=/path/to/abc
Type=Application
如果你把abc放到PATH环境变量列出的目录里,在Exec=这里可以只写abc,否则写全路径

当然gnome之外的桌面环境,并没有这么多讲究,不需要这么麻烦。
回复