Qt问题之 告别软件因系统默认中文输入法导致错误退出的烦恼

1. 问题

使用Qt进行研发时,遇到一个问题,当在系统默认输入法中文(英文输入法或者搜狗就不会触发闪退)的情况下,选中QTableWidget控件(QTableWidgetItem有焦点,但是不双击), 进行输入,会导致软件错误退出。

这个Bug在Qt的Bug记录里也存在:QTableWidgetItem cause stack overflow

2. 问题复现

输入以下代码,按照问题操作步骤,可复现问题。

cpp 复制代码
    ui->tableWidget->setCellWidget(0, 1, new QLineEdit);

3. 解决方案1 设置输入方式,紧急解决方案

cpp 复制代码
ui->tableWidget->setInputMethodHints(Qt::ImhHiddenText);

4. 解决方案2 每个设置Item的地方使用setCellWidget,非最优解

cpp 复制代码
    for (int i = 0; i < ui->tableWidget->rowCount(); ++i)
    {
        for (int j = 0; j < ui->tableWidget->columnCount(); ++j)
        {
            ui->tableWidget->setCellWidget(i, j, new QLineEdit);
        }
    }

5. 解决方案3 使用代理,首选建议

示例代码
.h

cpp 复制代码
// 自定义代理类,继承自 QStyledItemDelegate
class SpinBoxDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    SpinBoxDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}

    // 创建编辑器,当用户开始编辑单元格时调用
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override
    {
        QSpinBox *editor = new QSpinBox(parent);
        editor->setMinimum(0);
        editor->setMaximum(100);
        return editor;
    }

    // 设置编辑器的数据,将模型中的数据设置到编辑器中
    void setEditorData(QWidget *editor, const QModelIndex &index) const override
    {
        int value = index.model()->data(index, Qt::EditRole).toInt();
        QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
        spinBox->setValue(value);
    }

    // 将编辑器中的数据保存到模型中
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override
    {
        QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
        int value = spinBox->value();
        model->setData(index, value, Qt::EditRole);
    }

    // 更新编辑器的几何形状,确保编辑器显示在正确位置
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const override
    {
        editor->setGeometry(option.rect);
        QStyledItemDelegate::updateEditorGeometry(editor, option, index);
    }
};

调用:

cpp 复制代码
#include <QtWidgets>


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

    // 创建一个表格视图
    QTableView tableView;

    // 创建一个标准的表格数据模型
    QStandardItemModel model(4, 2);
    model.setHeaderData(0, Qt::Horizontal, "Integer");
    model.setHeaderData(1, Qt::Horizontal, "Square");

    // 为表格设置数据模型
    tableView.setModel(&model);

    // 创建一个自定义代理实例
    SpinBoxDelegate delegate;
    // 将代理应用到第一列
    tableView.setItemDelegateForColumn(0, &delegate);

    // 填充表格数据
    for (int row = 0; row < 4; ++row) {
        for (int column = 0; column < 2; ++column) {
            QModelIndex index = model.index(row, column);
            if (column == 0) {
                model.setData(index, row);
            } else {
                int value = row * row;
                model.setData(index, value);
            }
        }
    }

    tableView.show();

    return app.exec();
}
相关推荐
码界索隆14 小时前
Python转Java系列:语法与类型系统
java·开发语言·python
ch.ju14 小时前
Java程序设计(第3版)第四章——编译中的错误:无法覆盖
java·开发语言
huangdong_14 小时前
拼多多商品图片批量采集技术解析:webp格式转换与SKU图自动分类
windows
阿正的梦工坊14 小时前
【Rust】15-Rust 内存布局、Drop 顺序与 unsafe 边界
开发语言·rust
我认不到你14 小时前
【开源、教程】RAG全流程实现(java+完整代码):第二弹
java·开发语言·人工智能·深度学习·ai·语言模型·开源
AKA__Zas14 小时前
初识多线程plus(2.0)
java·开发语言·学习方法
Rabitebla14 小时前
C++ 多态详解:从概念到虚表底层原理(代码轰炸)
开发语言·c++
charlie11451419114 小时前
通用GUI编程技术——图形渲染实战(五十)——命中测试与鼠标事件路由:精确交互
c++·windows·架构·交互·图形渲染
console.log('npc')14 小时前
FigmaEX 汉化,免费使用,下载与安装指南(Windows/Mac)
windows·macos·ui·figma
砍材农夫14 小时前
python 如何一次性安装项目所有依赖包(pip和uv)
开发语言·python·pip·uv