提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
最近项目需要,要用QT去连接Oracle数据库,查阅大量资料后最终确定使用QT的oracle驱动QOCI去连接数据库,QT版本5.15.2,VS版本VS2019,oracle服务器版本oracle11g_64位,字符编码格式为AMERICAN_AMERICA.US7ASCII,最终连接上数据库之后,发现中文乱码,显示为一堆问号,尝试过修改环境变量和注册表的方式都无效,历时两周的摸索终于解决现在把解决方案和示例代码一并给出。
提示:以下是本篇文章正文内容,下面案例可供参考
一、乱码示意图
可以看到名称字段出现了乱码
二、解决方案
1.QT模型的选择
QStandardItemModel
QStandardItemModel:每项数据可以存任何内容,其最灵活,但是需要手写代码把每个数据导入到模型中
2.代码
头文件:A_QStandardItemModel .h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_A_QStandardItemModel.h"
#include <QStandardItemModel>
#include <QItemSelectionModel>
class A_QStandardItemModel : public QMainWindow
{
Q_OBJECT
public:
A_QStandardItemModel(QWidget* parent = nullptr);
~A_QStandardItemModel();
void InitialData();
bool ConnectDatabase();
void GetData();
public:
QStandardItemModel* theModel;//数据模型
QItemSelectionModel* theSelection;//选择模型
bool IsConnect;
private:
Ui::A_QStandardItemModelClass ui;
};
CPP文件:A_QStandardItemModel .cpp
#include "A_QStandardItemModel.h"
#include <QMessageBox>
#include <QSqlDatabase>
#include<QtSql/QSqlDatabase>
#include<QtSql/QSqlQuery>
#include<qsqlerror.h>
#include<qdebug.h>
A_QStandardItemModel::A_QStandardItemModel(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
InitialData();
IsConnect = ConnectDatabase();
GetData();
}
A_QStandardItemModel::~A_QStandardItemModel()
{}
void A_QStandardItemModel::InitialData()
{
theModel = new QStandardItemModel(this);//数据模型
theSelection = new QItemSelectionModel(theModel);//选择模型
ui.tableView->setModel(theModel);
ui.tableView->setSelectionModel(theSelection);
}
bool A_QStandardItemModel::ConnectDatabase()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QOCI");
//本地
db.setHostName("127.0.0.1"); //数据库服务端IP
db.setPort(1521); //端口
db.setDatabaseName("orcl"); //数据库服务名
db.setUserName("system"); //账号
db.setPassword("123"); //密码
if (db.open())
{
QString str = db.lastError().text();
qDebug() << db.lastError();
QMessageBox::information(this, u8"提示", u8"成功连接Oracle");
return true;
}
else
{
QString str = db.lastError().text();
qDebug() << db.lastError();
QMessageBox::information(this, u8"提示", u8"连接Oracle失败");
return false;
}
}
void A_QStandardItemModel::GetData()
{
QString Str = QString("SELECT id,UTL_RAW.cast_to_raw(name),age,height,PositionId FROM EmployeeInfo");//EmployeeInfo
QSqlQuery query;
query.prepare(Str);
int queryRow = 0;//统计查询的行数
if (query.exec(Str))
{
while (query.next())
{
queryRow++;
qDebug() << queryRow;
}
query.seek(-1);//重置查询的位置到第一个数据的前一位
if (queryRow > 0)
{
//设置数据库的行数和列数
theModel->setRowCount(queryRow);
theModel->setColumnCount(5);
//设置表头
theModel->setHeaderData(0, Qt::Horizontal, QStringLiteral("Id号")); //设置表头,如不设置则使用数据库中的默认表头
theModel->setHeaderData(1, Qt::Horizontal, QStringLiteral("名称"));
theModel->setHeaderData(2, Qt::Horizontal, QStringLiteral("年龄"));
theModel->setHeaderData(3, Qt::Horizontal, QStringLiteral("身高"));
theModel->setHeaderData(4, Qt::Horizontal, QStringLiteral("职位代码"));
queryRow = 0;//重置,用于表示填充的行数
while (query.next())
{
//获得模型的索引
QModelIndex index;
index = theModel->index(queryRow, 0);
theModel->setData(index, query.value(0).toString(), Qt::DisplayRole);
index = theModel->index(queryRow, 1);
theModel->setData(index, QString::fromLocal8Bit(query.value(1).toByteArray()), Qt::DisplayRole);//关键之处NAME显示不乱码的解决办法
index = theModel->index(queryRow, 2);
theModel->setData(index, query.value(2).toString(), Qt::DisplayRole);
index = theModel->index(queryRow, 3);
theModel->setData(index, query.value(3).toString(), Qt::DisplayRole);
index = theModel->index(queryRow, 4);
theModel->setData(index, query.value(4).toString(), Qt::DisplayRole);
queryRow++;//行数+1
}
}
}
}
总结
提示:这里对文章进行总结:
最终结果:
这里关键的操作步骤是如下两步这两步需要配合着使用才能解决乱码问题:
1.QString Str = QString("SELECT id,UTL_RAW.cast_to_raw(name),age,height,PositionId FROM EmployeeInfo");中UTL_RAW.cast_to_raw()函数的使用
2.theModel->setData(index, QString::fromLocal8Bit(query.value(1).toByteArray()), Qt::DisplayRole);//关键之处NAME显示不乱码的解决办法
最后在末尾要感谢:师从名剑山的博客_CSDN博客-日常积累,Qt,Qt 控件基础领域博主