Qt 实现汉字竖排输入

  • 目标
  • 难点
    • 尝试
  • 解决方案
    • 实现方法
      • 页面和文本框
      • 字体
    • 程序
  • 写在最后

目标

实现汉字竖排输入和显示(WYS/WYG),如图:

难点

竖排的汉字需要在同一个文本框,且光标是横向的

尝试

限制文本框宽度,每行只能显示一个字体,这样能间接实现竖排。但是缺点也很明显:

  1. 只能实现单行文本的竖排
  2. 光标是竖向的,这样看起来还是横排的,如下图:

解决方案

在仔细观察了word和wps的竖排文本框之后,我想出了一个解决办法:

  1. 先把文本框顺时针旋转90度,就可以解决光标竖向显示的问题;
  2. 将字体逆时针旋转90度,与文本框的旋转结合就可以实现汉字竖排(文本框顺时针旋转,字体逆时针旋转相同角度,最后显示出来的字体是没有旋转的,但是光标因为随着文本框旋转,变成横向的了)。

实现方法

页面和文本框

首先,在主窗口创建一个QGraphicsView;接着创建一个QGraphicsScene,显示在QGraphicsView上;然后在QGraphicsScene上绘制一个QGraphicsRectItem白色矩形作为页面,并以一定间距绘制QGraphicsPathItem作为行界。这样一个简单的线装书页面排版就形成了。
我使用的是QGraphicsTextItem作为可编辑的文本框(有尝试用QTextEdit,但是它不支持分页)。
创建QGraphicsTextItem,用SetPos()函数设置其位置(从右边第一行起)、SetFont()函数设置字体(字体是稍后的重点)、setTextWidth()函数设置文本框高度(如果不设置会默认不分行)、setTextInteractionFlags(Qt::TextEditorInteraction)函数实现文本可编辑、setRotation(90)函数实现文本框顺时针旋转90度。

字体

修改字体是实现这个程序的目标的重点。我这里使用的是FontForge。用它将windows系统自带的“华文宋体”的所有字形逆时针旋转了90度。具体方法如下:

  1. 导入字体:系统字体一般放在C:\Windows\Fonts中,复制其中的“华文宋体 常规”到另一个文件夹(防止把原字体改崩了)。然后导入FontForge.

  1. 旋转字体:全选之后,Element->Transformations->Transform。原点选择字形原点(Glyph Origin),添加旋转动作(Rotate),并把角度选为90、方向选择逆时针(Withershins)。这里需要提一下上面的Move动作,因为字形原点有时候并不在字形的正中心,比如英文和数字字形,所以旋转之后需要再移动,这就需要用到Move动作。这个我也没有弄得很清楚,我只做了旋转。

  1. 保存字体:这里的一些步骤是我自己摸索的,不专业,仅供参考。旋转完成之后,先Element->Add Extrema;然后再Element->Font Info->PS Names修改PS名称;接着在TTF Names中修改TTF名称;点击OK后它会让你修改UniqueID,点击Change修改即可。最后File->Generate Fonts,选择保存的文件夹,选择True Type类型,定义文件名,点击Generate即可。




最后生成的字体缩略图和预览图如下:


可以看出英文和数字的坐标还是有问题,这个后面继续研究。

程序

将生成的字体ttf文件放入Qt程序文件夹,并双击安装;然后在程序中安装该字体。
程序Mainwindow.cpp代码如下:

#include "mainwindow.h"
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QFont>
#include <QFontDatabase>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{//安装自定义字体QFontDatabase::addApplicationFont(QStringLiteral("‪D:/QTexm/textdocument/STSongV.ttf"));this->resize(800,600);   //重置主窗口大小QGraphicsView *view = new QGraphicsView(this);setCentralWidget(view); //将view作为中心窗口,主窗口中心显示QGraphicsScene *scene = new QGraphicsScene();scene->setBackgroundBrush(Qt::gray);view->setScene(scene);  //将scene放在view上显示QPen pen;pen.setColor(Qt::white);float mm = 1/0.26;   //将像素单位转换成毫米//绘制页面QGraphicsRectItem *pageRect = new QGraphicsRectItem();pageRect->setRect(0, 0, 400*mm, 300*mm);pageRect->setPen(pen);pageRect->setBrush(Qt::white);scene->addItem(pageRect);//绘制行界QGraphicsRectItem *rect = new QGraphicsRectItem(pageRect);rect->setRect(20*mm, 30*mm, 360*mm, 250*mm);pen.setColor(Qt::black);pen.setWidth(2*mm);rect->setPen(pen);for (int i = 1; i < 19; ++ i ){QGraphicsPathItem *line = new QGraphicsPathItem(rect);line->setPos(i*20*mm, 30*mm);pen.setWidth(0.5*mm);QPainterPath path;path.lineTo(0, 250*mm);line->setPen(pen);line->setPath(path);}QString text = "天地玄黄宇宙洪荒日月盈昃辰宿列张寒来暑往秋收冬藏闰余成岁律吕调阳云腾致雨露结为霜金生丽水玉出昆冈剑号巨阙珠称夜光果珍李奈菜重芥姜";QFont font("华文宋体竖",50);//创建文本框QGraphicsTextItem *textItem = new  QGraphicsTextItem(pageRect);//设置文本框textItem->setPos(380*mm, 30*mm);textItem->setPlainText(text);textItem->setFont(font);textItem->setTextWidth(font.pointSizeF()*20);textItem->setTextInteractionFlags(Qt::TextEditorInteraction);textItem->setRotation(90);    //旋转文本框}MainWindow::~MainWindow()
{}

写在最后

本人正在自己钻研怎么实现古籍数字化。如今的古籍电子资源一般都是影印版,以图片的形式呈现。本人计划开发一个适应古籍排版的文本编辑器。编辑器可以导出OFD或者PDF文件。这样使用者可以自己排版自己的线装书(想象一下自己编一本古文集或古诗集),也可以在阅读古籍的时候加入自己的注解和笔记,也方便传阅和修改。
这是一个不小的工程。本人不是计算机相关专业出身的,所以能力有限。如果有同好的话,欢迎让我抱大腿。而且,开发软件只是第一步,如果你也对传统书籍或传统文化感兴趣,并有志于将其与信息化的方式融合,或者以信息化的方式推广,那么欢迎聊一聊!

Qt 实现汉字竖排输入(QGraphicsTextItem+FontForge)相关推荐

  1. QT限制文本框输入的方法

    QT限制文本框输入的方法 界面编程的时候,对文本框的处理往往是个很头疼的事情: 一是焦点进入文本框时,从人性化考虑,应选择文本框中文本,方便输入: 二是,限制文本框的输入,只允许输入有效的文本,如果不 ...

  2. c语言中汉字编码,【C语言学习】C语言汉字编码。。。C语言中汉字的输入

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 以下是我本人通过实例得出的结论,没有参照任何参考书.可能有不对的地方. 哪里不对,情各位大虾指正. 在说明之前,本人编写了一个小代码. #include ...

  3. 一个简单的拼音输入法,实现常用汉字的输入

    /* 这是一个简单的拼音输入法,只有常用的汉字,输入拼音后, 再输入数字,选择所需要的拼音 */ #include <string.h> #include <stdio.h> ...

  4. input输入框限制中文汉字只能输入20个字符,英文10个字符!

    iput输入框限制中文汉字只能输入10个字符,英文20个字符! 产品提了一个需求,要求输入框输入汉字的时候只能输入10个汉字 英文的话只能输入20个,当时不知道怎么做,后来通过百度查找到了答案. @i ...

  5. Qt通讯录(语音输入+发邮件+发短信+头像)

    Qt通讯录(语音输入+发邮件+发短信+头像) 项目背景 功能 运行程序 关键技术 语音识别ASR 发送电子邮件 AddressBook5.0 Gitee地址 项目背景 作为一个Qt小白,迫于大一下学期 ...

  6. 汉字计算机输入的优越性论文,议论文阅读训练中国第五大发明汉字附答案作文...

    初中议论文阅读训练中国第五大发明汉字附答案 ①汉字是当今世界上仍在使用的最古老的文字.从甲骨文算起,已有3500年以土的历 史了.古埃及的圣体字.巴比伦的楔形文字.中美洲的古玛雅文字等相继成为历史的陈 ...

  7. 目前主要的计算机汉字输入方法是什么,详解常见的汉字的输入方法

    通过计算机书写文章.与他人交流必然涉及到汉字输入问题,将汉字输入到计算机是通过不同的汉字输入法实现的,目前比较常用的有:拼音.五笔字型.国标/区位.自然码.钱码.郑码等.常见汉字的输入方法,各有千秋, ...

  8. 计算机里汉字从输入到输出经过的编码,请描述一个汉字从输入到输出的处理过程。...

    请选B 关于一个汉字从输入到输出处理过程正确的是______. A.首先用汉字的外码将汉字输入,其次用汉字的字形码存储并处理汉字,最后用汉字的内码将汉字输出 B.首先用汉字的外码将汉字输入,其次用汉字 ...

  9. qt无法定位程序输入点解决方法

    qt无法定位程序输入点解决方法 更新日期:2020-05-12 14:53:22 来源:互联网 手机扫码继续观看 很多的小伙伴在使用电脑的时候肯定都遇到过QT无法定位程序输入点与动态链接库,给正常的使 ...

最新文章

  1. 程序员的日常,过于真实 | 每日趣闻
  2. C#如何把日期转成YYYYMMDDHHMMSSFFF的精确到毫秒的格式?
  3. 【机器学习】HOG+SVM进行车辆检测的流程及源码
  4. 中国殡葬行业投资战略建议与前景策略分析报告2022-2028年版
  5. 正圆锥体空间方程_你也可以理解“麦克斯韦方程组”
  6. python中计算排队等待时间_codewars(python)练习笔记十:计算超市排队时长
  7. ArcSDE数据库、文件地理数据库和个人地理数据库的区别
  8. jpush java api_JPush極光推送Java服務器端API
  9. pandas read_sql
  10. IGMP协议——IP组播之组管理协议
  11. 网络核心之数据交换 - 报文、分组交换
  12. oracle表的incremental,ODI IKM Oracle Incremental Update的四种探测处理策略
  13. 我的AI之路(52)--如何制作自己的UCF101数据集
  14. ★关于人类体质弱化的分析
  15. 三十.基于国民MCU 的COMP与ADC结合的实战功能模拟案例
  16. Receptive field 感受野 原理+计算+图解+空洞卷积hole
  17. Python获取下周一日期
  18. java 获取服务器上文件,java获取远程服务器上的文件
  19. 不在乎 -- 陆琪
  20. DAB-DETR: DYNAMIC ANCHOR BOXES ARE BETTER QUERIES FOR DETR翻译

热门文章

  1. 昆仑通态MCGSPRO串口接收工具
  2. PBJ | 华中科大宁康组揭示甘草根转录组-微生物群落-次级代谢产物调控模式
  3. DGVa:染色体结构变异数据库
  4. 大一计算机学科导论作业
  5. 【期末复习】北京邮电大学《数字内容安全》课程期末复习笔记(4. 多媒体安全)
  6. libtorch学习笔记(16)- Faste-RCNN的RPN如何训练以及训练的参数集
  7. [ts]typescript高阶之typeof使用
  8. 战地1服务器列表显示实际ping,《战地1》如何在游戏中随时查看网络质量 怎么调处网络效能表...
  9. 记住密码php代码,推荐10款记住密码的用法代码汇总
  10. 论文笔记:Neural Collaborative Filtering