【第一篇】Qt学习与使用---将数字转换成中文大写的形式

本文介绍了一种将阿拉伯数字转换为中文大写的算法,并详细解释了如何处理多个连续零及数值单位的问题,确保转换结果符合中文书写习惯。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.期望实现:

数字 ===> 中文大写

如:  

        123.0456                      ===>                                                   壹贰叁点零肆伍陆

        12003045.678              ===>                     壹仟贰佰零万叁仟零肆拾伍点陆捌

        32012003045.678        ===>    叁佰贰拾亿壹仟贰佰零万叁仟零肆拾伍点陆捌


2.基本思路:

2.1 将数字分成四部分 即: 符号+整数+“点”+小数

2.2 查表拼接---将每一位的数字对应到汉字,将汉字拼接上去。

整数部分有数值单位,小数部分不需要数值单位。


数字表

QStringList numerical_value  =   {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};

单位表

(这个表成员的多少 决定你能装换的最大数值范围)(这里给出的可以让你最大转换 1万亿之下的所有数字(小于1万亿,大于负1万亿)

QStringList numerical_unit   =   {"","拾","佰","仟","万","拾", "佰", "仟", "亿", "拾", "佰", "仟"};

3.难点:

实现查表,再拼接,这样做很简单。但是这样做的结果就是如此:

32012003045.678        ===>    叁佰贰拾零亿壹仟贰佰零拾零万叁仟零佰肆拾伍点陆捌

猛地一看,你可能觉得没什么,但这样的写法是不符合我们中国人读数字的习惯的。

3.1当出现多个连0的情况的时候,需要我们根据情况省略和跳过拼接。


3.2在省略零的时候,要注意分段省略,按照中国人的习惯,4位为一段。我按照 “”,“万”,“亿”将整数部分分成三段(因为我的数字范围是1万亿以下)。

如果不分段,可能会导致,“万”和“亿”的丢失。




4.代码

const QString number_Transfer_BigChinese(const double &Fnumber)
{

    if(qAbs(Fnumber)<0.01)   //保留2位小数时,近似看作零的情况
        return "零";


    //判断正负号
    QString numberSign;//存储符号
    if(Fnumber<0)
        numberSign = "(负数)";
   //将数据的绝对值 转换成字符串,如-58 转成 “58.00”
   QString number = QString::number(qAbs(Fnumber),'f',2);//qAbs绝对值 ,保留两位小数
   QString Left_of_Point;//整数部分
   int length =number.length()-3;//整数部分的长度,(精确度为2,去除小数和小数点)
   if(length>12)
   {
        //qDebug()<<"输入的数值超过范围!"
        return "输入的数值超过范围!";
   }

   QStringList numerical_unit   =   {"","拾","佰","仟","万","拾", "佰", "仟", "亿", "拾", "佰", "仟"};
   QStringList numerical_value  =   {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};

   //数数整数低位多少个连零
   int counter_0=0;
   for(int i =length-1;i>=0;i--)
   {
       if((number[i].toLatin1()-'0' )==0) //从个位开始,向高位走
           counter_0++;
       else
           break;

   }
   if(length==1 && counter_0==1) //0.x
       counter_0=0; //不进行过滤

   //1400  0.2

   for(int i=0,flag=1;i<length-counter_0;i++)
   {
        //5     8       1    2   3
        //伍 拾 捌       壹佰 贰拾 叁
       if((number[i].toLatin1()-'0')==0)
       {
           if((flag!=0 && (length-1-i)%4 != 0) || length ==1) //flag!=0  表示前一个数值 不为0
           Left_of_Point+="零"; //后面不用添加 单位
           if((length-1-i)%4 == 0) //如果0处于分段处,后面需添加单位
           Left_of_Point+=numerical_unit[length-1-i];//添加数值单位

           flag =0; //标记

       }
       else
       {
        flag =1;
        Left_of_Point+=numerical_value[number[i].toLatin1()-'0']; //'5'-'0'==5
        Left_of_Point+=numerical_unit[length-1-i];//添加数值单位

       }
   }
    //QString Right_of_Point;//小数点右侧,小数部分(保留两位)  xxxx.yy
    int totalLength = number.length();
    if(number[totalLength-2]=='0'&&number[totalLength-1]=='0')
    {
        QString Bigcn=numberSign+Left_of_Point+"吨";
        return Bigcn;
    }
    else if(number[totalLength-2]!='0'&&number[totalLength-1]=='0')
    {
        QString Bigcn=numberSign+Left_of_Point+"点"+numerical_value[number[totalLength-2].toLatin1()-'0']+"吨";
        return Bigcn;
    }
    else
    {
        QString Bigcn=numberSign+Left_of_Point+"点"+numerical_value[number[totalLength-2].toLatin1()-'0']+numerical_value[number[totalLength-1].toLatin1()-'0']+"吨";
        return Bigcn;
    }


    return "异常情况";
}

5.欢迎大家留言交流(转载请标明出处噢!(*  ̄3)(ε ̄ *))


<think>我们正在处理一个Qt编程问题,用户在使用QLabel的setText时遇到类型换或函数调用相关的错误。具体错误信息可能涉及int、key、Qt::Key、const等关键词。 根据用户描述,错误发生在设置label文本时,且提到了int key Qt::Key const error。这暗示错误可能事件处理(如键盘事件)中的键值处理有关,因为Qt::Key是枚举类型,而setText需要字符串。 回顾引用[1]中的示例,在键盘事件处理函数中,我们通过event->key()获取按下的键,返回的是int类型(实际上是Qt::Key枚举值)。如果用户试图直接将这个int值传递给setText,就会导致类型不匹配,因为setText要求QString。 另外,引用[3]展示了一个全局函数repolish,用于刷新样式,但当前问题可能不直接相关。 因此,错误原因很可能是:试图将键盘事件的键值(整数或枚举)直接设置为QLabel的文本,而没有将其换为字符串。 解决方案: 1. 将键值换为字符串。但注意,直接换整数(如65)可能不是用户想要的(比如用户想看到的是'A'而不是65)。 2. 使用Qt的枚举换功能,将Qt::Key换为可读的字符串。但注意,Qt::Key枚举值并不直接对应字符(例如,Qt::Key_A代表A键被按下,但和字符'A'不同,特别是当同时按下Shift时,我们可能得到大写字母)。 实际上,对于可打印字符,我们通常使用event->text()来获取实际输入的字符。对于非打印字符(如方向键、功能键),我们可以使用Qt::Key枚举值的名称字符串。 步骤: 在键盘事件处理函数中: - 如果要显示按下的键对应的字符(例如,按A键显示'A'),则使用event->text()。 - 如果要显示键的枚举名称(例如,按Escape键显示"Escape"),则需要将Qt::Key枚举值换为字符串。 但是,Qt没有直接提供将Qt::Key枚举值换为字符串的函数。我们可以使用QKeySequence或自定义映射。 示例代码(来自引用[1]的扩展): ```cpp void MyWidget::keyPressEvent(QKeyEvent *event) { // 示例1:显示按下的键的字符(如果是可打印字符) QString str1 = event->text(); ui->label->setText(str1); // 示例2:显示按下的键的名称(如"Escape") int key = event->key(); QString str2; if (key == Qt::Key_Escape) { str2 = "Escape"; } else if (key >= Qt::Key_A && key <= Qt::Key_Z) { // 注意:这里我们得到的是键值,而不是字符。例如,按A键,这里得到的是Qt::Key_A(65),但可能我们想显示的是'A' // 所以,通常我们更倾向于使用event->text()来获取字符 // 如果要显示键的名称,我们可以使用QKeySequence str2 = QKeySequence(key).toString(); } else { // 其他键使用QKeySequence换 str2 = QKeySequence(key).toString(); } // 或者,更通用的方法:使用枚举值到字符串的映射(但Qt没有直接提供,所以我们可以用QKeySequence) // 注意:QKeySequence对于单个键会返回一个字符串,例如Qt::Key_A会返回"A"(大写),但这不是键的名称,而是键对应的字符(根据键盘布局) // 实际上,QKeySequence::toString()返回的是该键在键盘布局中对应的字符(或组合键的字符串表示),并不适合显示键的名称。 // 因此,对于非打印键(如功能键、方向键等),我们可以使用一个映射函数: // 这里我们使用一个简单的方法:使用QMetaEnum来获取枚举名称(但注意,Qt::Key枚举并没有在元对象系统中注册,所以不能直接用QMetaEnum) // 另一种方法是使用静态的字符串映射表。 // 实际上,我们可以这样: // 使用QKeyEvent::toString(),这个函数返回一个描述按键的字符串(包括修饰键和键名)。例如,按下Shift+A,返回"Shift+A" // 但注意:这个函数返回的是组合键的字符串,如果只想显示键名,可以单独处理。 // 推荐使用:event->toString() 或者 event->text() 根据需求选择 // 例如,对于字符输入,使用event->text();对于功能键等,使用event->toString()可能更详细。 // 但是,用户可能只想显示按下的键的名称(不带修饰键),那么我们可以使用以下方法: QString keyName = QKeySequence(key).toString(); // 但是,对于非打印键,QKeySequence可能返回空字符串。所以,我们可以使用自定义的映射函数。 // 由于没有现成的完美方法,我们可以参考Qt的源码,或者使用第三方库。但简单情况下,我们可以自己处理一些常用键。 // 因此,如果用户想要显示键的名称(如"Escape", "Enter", "A"等),我们可以这样: // 注意:QKeySequence对于字母键返回的是大写字母,对于数字键返回数字,对于功能键,在Qt5.12及以上版本,QKeySequence::toString()可以返回如"Esc"这样的字符串(但文档没有明确保证)。 // 实际上,在Qt5中,QKeyEvent::key()返回的键值,我们可以通过QKeySequence(key).toString()得到非空字符串(对于大多数键),但有些键可能返回空。 // 所以,更可靠的方法是使用一个switch语句来映射常用键。 // 综合建议:如果用户想显示按下的键的字符(比如输入框),则用event->text();如果用户想显示键的名称(比如快捷键设置界面),则使用自定义的映射(或使用QKeySequence,但注意其局限性)。 // 对于简单调试,我们可以用event->key()的整数值,但这不是用户想要的。 // 因此,回到问题,用户可能是在事件处理函数中直接使用了event->key()(返回int)来设置文本,导致类型错误。我们应当将其换为字符串。 // 最简单的调试方式:将整数换为字符串 QString str3 = QString::number(key); ui->label->setText(str3); // 这样会显示键的整数值(如Qt::Key_Escape是16777216) // 显然,用户不想显示整数,而是键的名称。 // 所以,我们可能需要一个换函数: QString keyToString(int key) { switch (key) { case Qt::Key_Escape: return "Escape"; case Qt::Key_Tab: return "Tab"; case Qt::Key_Backtab: return "Backtab"; case Qt::Key_Backspace: return "Backspace"; case Qt::Key_Return: return "Return"; case Qt::Key_Enter: return "Enter"; // ... 其他键 default: if (key >= Qt::Key_Space && key <= Qt::Key_AsciiTilde) { // 可打印字符 return QChar(key); } // 尝试用QKeySequence QString s = QKeySequence(key).toString(); if (!s.isEmpty()) return s; return QString("Key(%1)").arg(key); } } // 然后使用: QString str4 = keyToString(key); ui->label->setText(str4); } ``` 但是,上述自定义函数较为复杂。实际上,Qt提供了QKeyEvent::text()用于可打印字符,而对于其他键,我们可以使用QKeyEvent::key()返回的枚举值,然后通过一个映射表来获取字符串(Qt本身没有提供,但我们可以自己写一部分)。 另外,注意用户错误中提到的“const error”,可能是由于在事件处理函数中试图修改const对象?但根据错误描述,更可能是类型不匹配。 总结错误解决步骤: 1. 确保在设置文本时,传递的是QString类型。 2. 如果使用event->key(),需要将其换为字符串,但直接换整数可能不是想要的,建议使用上述方法之一(event->text()或自定义换函数)。 因此,用户可能犯了这样的错误: ```cpp // 错误示例 void MyWidget::keyPressEvent(QKeyEvent *event) { // 错误:setText需要QString,但event->key()返回int ui->label->setText(event->key()); // 编译错误:没有匹配的setText函数,因为int不能隐式换为QString } ``` 正确做法: ```cpp // 正确示例1:使用event->text(),显示按下的键对应的字符(如果是可打印字符) void MyWidget::keyPressEvent(QKeyEvent *event) { ui->label->setText(event->text()); } // 正确示例2:显示键的整数值(调试用) void MyWidget::keyPressEvent(QKeyEvent *event) { ui->label->setText(QString::number(event->key())); } // 正确示例3:显示键的名称(自定义换) // 需要先定义换函数(如上文的keyToString),或者使用其他方法 ``` 另外,用户提到“Qt ui label setText int key Qt::Key const error”,可能还涉及const修饰符。注意,QKeyEvent是const对象,但我们并没有修改它,所以不会导致const错误。错误更可能是类型不匹配。 因此,用户应该检查是否在setText中传递了正确的类型(QString),并考虑使用event->text()来获取字符串。 如果用户想要显示非打印键的名称(如方向键),则建议使用自定义的换函数,或者使用第三方库(如QtKeyExtension)。 最后,注意引用[2]提醒要安装charts模块,但当前问题不涉及,所以忽略。 引用[3]展示了一个全局函数,用于刷新样式,当前问题无关。 所以,回答用户: 错误可能是因为你直接将键盘事件的键值(int类型)传递给setText,而setText需要QString类型。请使用event->text()获取可打印字符,或者将键值换为字符串。对于非打印键,需要自定义换函数。 示例代码: ```cpp // 在键盘事件处理函数中 ui->label->setText(event->text()); // 显示按下的键对应的字符(可打印字符) // 或者,显示键的整数值(调试用) ui->label->setText(QString::number(event->key())); // 或者,自定义换函数(这里只处理部分键) QString keyToString(int key) { switch (key) { case Qt::Key_Escape: return "Escape"; case Qt::Key_Up: return "Up"; case Qt::Key_Down: return "Down"; case Qt::Key_Left: return "Left"; case Qt::Key_Right: return "Right"; // ... 其他键 default: // 如果是可打印字符,使用QChar if (key >= Qt::Key_Space && key <= Qt::Key_AsciiTilde) return QChar(key); else return "Key_" + QString::number(key); } } // 使用 ui->label->setText(keyToString(event->key())); ``` 注意:event->text()对于非打印键返回空字符串,所以如果用户按的是方向键,则用event->text()会显示空,此时应该用event->key()换。 因此,根据需求选择方法。 如果用户需要显示所有键的通用方法,可以考虑使用QKeySequence(key).toString(),但注意它可能返回空或非预期的字符串(比如字母键返回大写字母)。在Qt5中,对于功能键,QKeySequence::toString()返回的是本地化的字符串,但可能不是英文名称。 另一种方法是使用QMetaEnum(但需要将Qt::Key枚举注册到元对象系统,实际上并没有),所以不推荐。 因此,对于简单应用,建议使用自定义映射处理常用键,其他键用整数换。 最后,确保在事件处理函数中正确声明参数:QKeyEvent *event,并且事件已被传递到该函数(没有忽略事件)。 相关问题: 1. 如何获取Qt键盘事件中的键值? 2. 如何将Qt::Key枚举值换为可读的字符串? 3. QKeyEvent::text()和QKeyEvent::key()有什么区别? 4. 如何处理Qt中的非打印键(如功能键)? 5. 为什么setText不能直接接受整数参数?</think>### Qt 中设置 QLabel 文本时类型换错误的解决方案 在使用 Qt 设置 QLabel 文本时遇到类型换错误,通常是因为试图将 `int` 类型(如键盘键值)直接传递给 `setText()` 方法。该方法需要 `QString` 类型参数,而 `Qt::Key` 枚举值本质是整数,直接使用会导致类型不匹配。以下是详细解决方案: --- ### 错误原因分析 1. **类型不匹配** `QLabel::setText()` 只接受 `QString` 类型参数,但键盘事件返回的键值是 `int` 类型(如 `Qt::Key_Escape` 对应整数值 `16777216`)。 2. **常见错误代码示例** ```cpp // 错误:直接使用 int 键值 void Widget::keyPressEvent(QKeyEvent *event) { ui->label->setText(event->key()); // 编译错误! } ``` --- ### 正确解决方案 #### 方法 1:换为字符串(显示键值) 使用 `QString::number()` 将整数键值为字符串: ```cpp void Widget::keyPressEvent(QKeyEvent *event) { int keyValue = event->key(); // 获取键值(int 类型) ui->label->setText(QString::number(keyValue)); // 正确换 } ``` #### 方法 2:显示可读键名(推荐) 通过 `QKeyEvent::text()` 获取键的字符表示(支持可打印字符): ```cpp void Widget::keyPressEvent(QKeyEvent *event) { QString keyText = event->text(); // 返回 QString(如 "A"、"Esc") if (!keyText.isEmpty()) { ui->label->setText("Pressed: " + keyText); } } ``` #### 方法 3:自定义键名映射 对特殊键(如方向键)使用映射表: ```cpp void Widget::keyPressEvent(QKeyEvent *event) { QString keyName; switch (event->key()) { case Qt::Key_Escape: keyName = "ESC"; break; case Qt::Key_Up: keyName = "UP"; break; case Qt::Key_Down: keyName = "DOWN"; break; default: keyName = event->text(); // 默认处理可打印字符 } ui->label->setText(keyName); } ``` --- ### 关键注意事项 1. **`text()` vs `key()` 的区别** - `event->text()`:返回 `QString`,适合可打印字符(如字母、数字- `event->key()`:返回 `int`,需手动换,适合功能键 2. **事件处理函数签名** 必须正确声明事件参数为 `QKeyEvent*` 并包含 `const`: ```cpp // 正确声明(注意 const 修饰符) void keyPressEvent(QKeyEvent *event) override; // 在头文件中声明 ``` 3. **调试技巧** 使用 `qDebug()` 检查键值: ```cpp qDebug() << "Key pressed:" << event->key() << "Text:" << event->text(); ``` --- ### 完整示例代码 ```cpp // widget.h class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); protected: void keyPressEvent(QKeyEvent *event) override; // 声明键盘事件 private: Ui::Widget *ui; }; // widget.cpp void Widget::keyPressEvent(QKeyEvent *event) { QString msg = "Key: "; if (event->key() == Qt::Key_Escape) { msg += "ESC"; } else { msg += event->text(); // 自动处理可打印字符 } ui->label->setText(msg); } ``` --- ### 常见问题排查 1. **编译错误 `no matching function for call to 'setText'`** 确保传递的是 `QString` 类型,检查是否误传 `int` 或 `Qt::Key`。 2. **运行时显示空文本** 功能键(如方向键)的 `event->text()` 返回空字符串,需改用 `switch-case` 处理。 3. **事件未被触发** 确保窗口已获得焦点(通过 `setFocusPolicy(Qt::StrongFocus)` 设置)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值