大连密封材料 发表于 2025-4-11 19:29:55

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

1. 问题

利用Qt进行研发时,遇到一个问题,当在系统默认输入法中文(英文输入法或者搜狗就不会触发闪退)的情况下,选中QTableWidget控件(QTableWidgetItem有核心,但是不双击), 进行输入,会导致软件错误退出。
这个Bug在Qt的Bug记录里也存在:QTableWidgetItem cause stack overflow
https://i-blog.csdnimg.cn/img_convert/fc25cc6ce0c5b4aeaf4220391a061209.png
2. 问题复现

输入以下代码,按照问题操作步骤,可复现问题。
    ui->tableWidget->setCellWidget(0, 1, new QLineEdit);
https://i-blog.csdnimg.cn/img_convert/720e6d1296db3e545750c58befebef4d.png
3. 解决方案1 设置输入方式,紧急解决方案

ui->tableWidget->setInputMethodHints(Qt::ImhHiddenText);
4. 解决方案2 每个设置Item的地方利用setCellWidget,非最优解

    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
// 自定义代理类,继承自 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);
    }
};
调用:
#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();
}
https://i-blog.csdnimg.cn/img_convert/3f31489c85fbe9fb506cfafc30af98e5.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Qt问题之 告别软件因系统默认中文输入法导致错误退出的烦恼