`
oceanG_Y
  • 浏览: 49854 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

QT知识小结(二)

    博客分类:
  • QT
阅读更多

1、取消对话框最大,最小按钮

     

      #include <Qt>

 

       QPixmap splImg("images//Splash.png");

       QPalette p;

        p.setBrush(splshDlg.backgroundRole(),QBrush(splImg));

        splshDlg.setPalette(p);

        splshDlg.setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint);//没有标题栏

        //splshDlg.setAttribute(Qt::WA_TranslucentBackground);

       splshDlg.show();

 

2、设置启动画面

       #include <Qt/qsplashscreen.h>

 

          QSplashScreen *splash=new QSplashScreen;

          splash->setPixmap(QPixmap("images//Splash.png"));

          splash->show();

         //splash->finish(&dlg);

         //delete splash;

 

3、对话框大小固定,不允许用户拉大,拉小

      dlg.setMaximumHeight(350);

      dlg.setMaximumWidth(450);

 

      dlg.setMinimumHeight(350);

      dlg.setMinimumWidth(450);

 

4、设置QT程序字体

    QFont font("Fangsong Ti");

         #ifdef WIN32

font.setFamily("宋体");

font.setPointSize(12);

         #else

font.setFamily("Song");

font.setPointSize(15)

          #endif

//a.setFont(font);

 

 5、汉字为乱码的解决方法

      #include <Qt/qtextcodec.h>

       QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));

 

 6QT连接数据库

  

连接数据库需要的头文件:

#include <QSqlDatabase>

#include <QSqlQuery>

 

1、连接微软的Access-------------------------------------------------------------

 QSqlDatabase ldb = QSqlDatabase::addDatabase("QODBC");

 ldb.setDatabaseName("DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=system.mdb;UID=;PWD=xiaozhuset");

bool ok = ldb.open();

//新定义一个查询集合,并指定 链接关键字。 如果有多个连接,可以随意指定一个你需要的。

QSqlQuery mquery=QSqlQuery::QSqlQuery(ldb);

if(ok)

{

  bool isok=mquery.exec("select * from sql_set;");

 if (!isok)

 {

   ldb.close();

   return -1;

  }

 

//这个是必须的,因为查处的结果集当前位置不在第一条记录上。

mquery.next();

 

QString sHostName=mquery.value(1).toString();

QString sDatabaseName=mquery.value(2).toString();

QString sUserName=mquery.value(3).toString();

QString sPassword=mquery.value(4).toString();

 

//清除结果集

mquery.clear();

// 如果该连接不再使用,就可以关闭。

ldb.close();

 

//这里是将从数据库读出的数据写到一个list控件里

ui.list_out->insertItem(ui.list_out->count(),sHostName);

ui.list_out->insertItem(ui.list_out->count(),sDatabaseName);

 

}

else

{

// 打开本地数据库失败,

QMessageBox::critical(0, QObject::tr("读取Access数据库错误!"),db.lastError().text());

return -1;

}

 

 

2、连接mssql2000 数据库--------------------------------------------------------------------------------------------

QString strDatabaseName = QString("DRIVER={SQL Server};Server=(%1);Database=%2").arg("local").arg(sDatabaseName);

 

db=QSqlDatabase::addDatabase("QODBC","db"); // 使用odbc数据库驱动

db.setHostName(sHostName);

db.setPort(1433);

db.setDatabaseName(strDatabaseName); // 我们之前建立的数据库连接关键字

db.setUserName(sUserName);

db.setPassword(sPassword);

bool ok = db.open(); //尝试连接数据库

if(ok)

{

menuset_set->db=db;

// 这里用sa已经成功连上数据库

return 0;

}

else

{

// 打开数据库失败,

QMessageBox::critical(0, QObject::tr("数据库连接错误!"),db.lastError().text());

return -2;

}

mssql2000数据库连接的使用和Access连接使用方法一样。

QSqlQuery mquery=QSqlQuery::QSqlQuery(db);

bool ok1=mquery.exec("select * from CarteMenu;");

if (ok1==false)return -1;

QString menu_mkey=mquery.value(13).toString();

QString strmenu_lang=mquery.value(3).toString();

//清除结果集

mquery.clear();

 

3、连接mysql 数据库

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); // 使用mysql数据库驱动

db.setHostName("localhost");

db.setDatabaseName("exampledb"); // 数据库名称

db.setUserName("sa"); // 用户名

db.setPassword("1"); // 密码

bool ok = db.open(); // 尝试连接数据库

if(ok)

{

QSqlQuery myquery;

if(myquery.exec("select * from employeedb"))

{

int num = 0;

if(db.driver()->hasFeature(QSqlDriver::QuerySize))

{

num = myquery.size(); // 如果支持结果影响的行数,那么直接记录下来

}

else

{

myquery.last(); //否则定位到结果最后

num = myquery.at() + 1;

}

//这里添加数据库的查询结果处理操作

 

}

else // 如果查询失败

{

QSqlError error = myquery.lastError();

}

}

else // 打开数据库失败

{

 

}

 

7、验证当前系统支持哪些数据库

 

#include <QApplication>

#include <QSqlDatabase>

#include <QStringList>

#include <QDebug>

 

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

QApplication app(argc, argv);

 

qDebug() << "Available drivers:";

QStringList drivers = QSqlDatabase::drivers();

foreach(QString driver, drivers)

qDebug() << "\t" << driver;

 

QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");

qDebug() << "ODBC driver valid?" << db.isValid();

}

 

8QT连接SQL Server2000报错

     出错信息:[Microsoft][ODBC SQL Server Driver][SQL Server]用户 'sa' 登录失败。原因: 未与信任 SQL Server 连接相关联。 QODBC3: Unable to connect

 

    解决方法

           找到解决这个问题的方法了,这样问题解决了。

             这一问题一般是由于SQL Server未集成Windows身份验证导致的,所以解决方案为:

            1、打开SQL Server企业管理器。

            2、选择服务器名称上右键选择“编辑SQL Server注册属性”,然后在对话框中选择“使用windows身份验证”。

            3、同样右键,选择“属性”,然后打开“安全性”选项卡。

            4、在选项卡中,选择身份验证为“SQL Server Windows ”,其他不变。

 

9QT数据库操作

         

qt-win-commercial-src-4.3.1、qt-x11-commercial-src-4.3.1

Microsoft Visual C++ 6.0、KDevelop 3.5.0

Windows Xp、Solaris 10、Fedora 8

SQL Server、Oracle 10g Client

*********************************************************************************

■、驱动编译

这里要提及两个数据库驱动,分别是ODBCOCI

Windows操作系统中编译ODBC驱动:

执行以下命令,会在%QTDIR%\plugins\sqldrivers目录下面生成qsqlodbc4.dll

cd %QTDIR%\src\plugins\sqldrivers\odbc

qmake -o Makefile odbc.pro

nmake

Unix操作系统下编译unixODBC驱动:

unixODBC可以在http://www.unixodbc.org下载。这里假定unixODBC安装在/usr/local/unixODBC。

执行以下命令,会在$QTDIR/plugins/sqldrivers目录下面生成qsqlodbc4.a

cd $QTDIR/src/plugins/sqldrivers/odbc

qmake "INCLUDEPATH+=/usr/local/unixODBC/include" "LIBS+=-L/usr/local/unixODBC/lib -lodbc"

make

Windows操作系统中编译OCI驱动:

这里假定Oracle Client安装在C:\oracle。添加oci.dll动态连接库的环境变量c:\oracle\bin

set INCLUDE=%INCLUDE%;c:\oracle\oci\include

set LIB=%LIB%;c:\oracle\oci\lib\msvc

cd %QTDIR%\src\plugins\sqldrivers\oci

qmake -o Makefile oci.pro

nmake

Unix操作系统下编译OCI驱动:

当然根据你的oracle修正下相应的版本号。

cd $QTDIR/src/plugins/sqldrivers/oci

qmake -o Makefile "INCLUDEPATH+=/usr/include/oracle/10.1.0.3/client/" "LIBS+=-L/usr/lib/oracle/10.1.0.3/client/lib" oci.pro

make

在程序中包含头文件

#include <QtSql>

在程序的.pro文件中添加

QT += sql

 

■、数据库连接

这里则要提及单一数据库连接和多个数据库连接:

单一数据库连接:

static bool sqlConnection(const QString& HostName,

const QString& DatabaseName,

const QString& UserName,

const QString& Password)

{

QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");

db.setHostName(HostName);

db.setDatabaseName(DatabaseName);

db.setUserName(UserName);

db.setPassword(Password);

if(!db.open())

{

QMessageBox::critical(0, QObject::tr("Error"),

QObject::tr("The database reported an error: %1").arg(db.lastError().text()));

return false;

}

//Qt数据库连接后,运行"SET NAMES 'UTF8'"语句或"SET NAMES 'GBK'"

//db.exec("SET NAMES 'UTF8'");

return true;

}

//多个数据库连接

static bool sqlConnections()

{

// 创建一个名为odbc的连接

QSqlDatabase *odbc = QSqlDatabase::addDatabase( "QODBC", "ODBC" );

if ( ! defaultDB ) {

qWarning( "Failed to connect to odbc driver" );

return FALSE;

}

odbc->setDatabaseName( DB_ODBC_DBNAME );

odbc->setUserName( DB_ODBC_USER );

odbc->setPassword( DB_ODBC_PASSWD );

odbc->setHostName( DB_ODBC_HOST );

if ( ! odbc->open() ) {

qWarning( "Failed to open sales database: " + odbc->lastError().driverText() );

qWarning( odbc->lastError().databaseText() );

return FALSE;

}

// 创建一个名为oracle的连接

QSqlDatabase *oracle = QSqlDatabase::addDatabase( "QOCI", "ORACLE" );

if ( ! oracle ) {

qWarning( "Failed to connect to oracle driver" );

return FALSE;

}

oracle->setDatabaseName( DB_ORACLE_DBNAME );

oracle->setUserName( DB_ORACLE_USER );

oracle->setPassword( DB_ORACLE_PASSWD );

oracle->setHostName( DB_ORACLE_HOST );

if ( ! oracle->open() ) {

qWarning( "Failed to open orders database: " + oracle->lastError().driverText() );

qWarning( oracle->lastError().databaseText() );

return FALSE;

}

return TRUE;

}

QSqlDatabase维护着通过addDatabase()这个静态函数返回的的连接指针。

如果有移去一个连接,先调用QSqlDatabase::close()来关闭连接,然后通过静态函数QSqlDatabase::removeDatabase()来移除连接。

int main(int argc, char *argv[])

{

QApplication app(argc, argv);

QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());

QTextCodec::setCodecForTr(QTextCodec::codecForLocale());

QFont font("Times", 9, QFont::Normal, FALSE);

app.setFont(font);

//连接单一数据库

if (!sqlConnection("10.0.0.3", "qjkzdb", "sa", "syth7777"))

return 1;

//连接多个数据库

if (!sqlConnections())

return 1;

// 数据库被成功打开,得到它们的指针:

QSqlDatabase *oracledb = QSqlDatabase::database( "ORACLE" );

// 现在我们可以在oracle连接或默认连接上执行SQL命令

...

return app.exec();

}

 

■、SQL执行操作

QSqlQuery提供了对数据库记录的SelectInsertUpdateDelete操作。

SELECT操作:

QSqlQuery query;

query.exec("SELECT name, salary FROM employee WHERE salary > 50000");

while (query.next()) {

QString name = query.value(0).toString();

int salary = query.value(1).toInt();

qDebug() << name << salary;

}

通过QSqlQuery::next()QSqlQuery::previous()QSqlQuery::first()QSqlQuery::last()QSqlQuery::seek()

可以得到下一条、上一条、第一条、最后一条、任意一条记录的位置。

INSERT操作:

//单一插入数据

QSqlQuery query;

query.prepare("INSERT INTO employee (id, name, salary) "

"VALUES (:id, :name, :salary)");

query.bindValue(":id", 1001);

query.bindValue(":name", "Thad Beaumont");

query.bindValue(":salary", 65000);

query.exec();

//批量插入数据

QSqlQuery query;

query.prepare("insert into myTable values (?, ?)");

QVariantList ints;

ints << 1 << 2 << 3 << 4;

query.addBindValue(ints);

QVariantList names;

names << "Harald" << "Boris" << "Trond" << QVariant(QVariant::String);

query.addBindValue(names);

if (!query.execBatch())

qDebug() << query.lastError();

UPDATE操作:

QSqlQuery query;

query.prepare("UPDATE employee SET salary = ? WHERE id = 1003");

query.bindValue(0, 70000);

query.exe();

DELETE操作:

QSqlQuery query;

query.exec("DELETE FROM employee WHERE id = 1007");

事务处理:

QSqlDatabase::database().transaction();

QSqlQuery query;

query.exec("SELECT id FROM employee WHERE name = 'Torild Halvorsen'");

if (query.next()) {

int employeeId = query.value(0).toInt();

query.exec("INSERT INTO project (id, name, ownerid) "

"VALUES (201, 'Manhattan Project', "

+ QString::number(employeeId) + ")");

}

QSqlDatabase::database().commit();

如果数据库引擎支持事务处理,则函数QSqlDriver::hasFeature(QSqlDriver::Transactions)将返回真。

可以通过调用QSqlDatabase::transaction()来初始化一个事务处理。之后执行你想在该事务处理的工作。

完了再执行QSqlDatabase::commit()来提交事务处理或QSqlDatabase::rollback()取消事务处理。

这里在举个QSqlDriver::hasFeature(QSqlDriver::QuerySize)例子,可以较快的统计查询记录行数。

QSqlQuery query;

int numRows;

query.exec("SELECT name, salary FROM employee WHERE salary > 50000");

QSqlDatabase defaultDB = QSqlDatabase::database();

if (defaultDB.driver()->hasFeature(QSqlDriver::QuerySize)) {

numRows = query.size();

} else {

// this can be very slow

query.last();

numRows = query.at() + 1;

}

存储过程:

AsciiToInt()是数据库中的一个存储过程。

但我在网上以前好像看过说是SQL Server中的存储过程是通过"EXEC"完成的,而不是"CALL",这里我不确定!留下一个疑问吧~

QSqlQuery query;

query.prepare("CALL AsciiToInt(?, ?)");

query.bindValue(0, "A");

query.bindValue(1, 0, QSql::Out);

query.exec();

int i = query.boundValue(1).toInt(); // i is 65

 

■、使用SQL Model

QSqlQueryModel:一个只读的读取数据库数据的模型。

QSqlTableModel:一个可读写的单一表格模型,可以不用写SQL语句。

QSqlRelationalTableModelQSqlTableModel的一个子类,可多表关联在一起。

这些类都继承于QAbstractTableModel,而它们又都继承于QAbstractItemModel

QSqlQueryModel 只读模式,基于SQL查询基础。

QSqlQueryModel model;

model.setQuery("SELECT * FROM employee");

for (int i = 0; i < model.rowCount(); ++i) {

int id = model.record(i).value("id").toInt();

QString name = model.record(i).value("name").toString();

qDebug() << id << name;

}

QSqlTableModel 可对单一表操作,进行读写操作。

//读取数据

QSqlTableModel model;

model.setTable("employee");

model.setFilter("salary > 50000");

model.setSort(2, Qt::DescendingOrder);

model.select();

for (int i = 0; i < model.rowCount(); ++i) {

QString name = model.record(i).value("name").toString();

int salary = model.record(i).value("salary").toInt();

qDebug() << name << salary;

}

//通过QSqlTableModel::setRecord()修改数据

for (int i = 0; i < model.rowCount(); ++i) {

QSqlRecord record = model.record(i);

double salary = record.value("salary").toInt();

salary *= 1.1;

record.setValue("salary", salary);

model.setRecord(i, record);

}

model.submitAll();

//通过QSqlTableModel::setData()update一条记录

model.setData(model.index(row, column), 75000);

model.submitAll();

//insert一条记录

model.insertRows(row, 1);

model.setData(model.index(row, 0), 1013);

model.setData(model.index(row, 1), "Peter Gordon");

model.setData(model.index(row, 2), 68500);

model.submitAll();

//delete一条记录

model.removeRows(row, 5);

model.submitAll();

函数QSqlTableModel::submitAll()确保记录写入数据库中。

QSqlRelationalTableModel 通过外键实现了多表关联。

//employee表中关联city表、country表。

model->setTable("employee");

model->setRelation(2, QSqlRelation("city", "id", "name"));

model->setRelation(3, QSqlRelation("country", "id", "name"));

■、数据呈现视图中

QSqlQueryModelQSqlTableModelQSqlRelationalTableModel一般都是借助QListViewQTableViewQTreeView吧数据呈现出来的~

这里我并不想对QTableView详细讲解,这里不做过多的介绍了,也许会在以后单独QTableViewQTableWidget详细介绍。

数据库部分是这次的重点!

继续在对QSqlRelationalTableModel这个作以讲解补充,因为上面提及的实在太少了。

QSqlRelationalTableModel model;

model->setTable("employee");

model->setRelation(2, QSqlRelation("city", "id", "name"));

model->setRelation(3, QSqlRelation("country", "id", "name"));

//设置标题头部标签信息

model->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));

model->setHeaderData(1, Qt::Horizontal, QObject::tr("Name"));

model->setHeaderData(2, Qt::Horizontal, QObject::tr("City"));

model->setHeaderData(3, Qt::Horizontal, QObject::tr("Country"));

//值得注意的是,在查询时应该明确指明那个表的数据信息,以下两种方式是等价的。

model.setFilter(tr("city.name = '%1'").arg("Mucich"));

//model.setFilter(tr("employee.cityid = %1").arg(312));

model.select();

//借助QTableView,把数据信息显示出来,

QTableView *view = new QTableView;

view->setModel(model);

//将表中的项,设计为不能编辑模式

view->setEditTriggers(QAbstractItemView::NoEditTriggers);

view->show();

在将一种通过QSqlField进行InsertUpdateDelete的操作。上边的例子,继续~

QSqlField idField("id", QVariant::Int);

QSqlField nameField("name", QVariant::String);

QSqlField cityIdField("cityId", QVariant::Int);

QSqlField countryIdField("countryId", QVariant::Int);

//一条记录 Id = 12Name = vic.MINgCity = ShenYangCountry = China(沈阳区号024、中国086)

idField.setValue(12);

nameField.setValue("vic.MINg");

cityIdField.setValue(24);

countryIdField.setValue(86);

//insert一条记录,-1表示在最尾端加入

QSqlRecord record;

record.append(idField);

record.append(nameField);

record.append(cityIdField);

record.append(countryIdField);

model->insertRecord(-1, record);

//update一条记录, row表示要修改的行

QSqlRecord record = model->record(row);

record.replace(1, nameField);

record.replace(2, cityIdField);

record.replace(3, countryIdField);

model->setRecord(row, record);

//delete一条记录, row表示要修改的行

model->removeRow(row);

 

■、数据呈现窗体中

通过QDataWidgetMapper可以在窗体控件与数据库中的记录关联在一起。

QDataWidgetMapper *mapper = new QDataWidgetMapper;

mapper->setModel(model);

mapper->addMapping(idSpinBox, 0);

mapper->addMapping(nameLineEdit, 1);

mapper->addMapping(cityComboBox, 2);

mapper->addMapping(countryComboBox, 3);

//可以通过toFirst()toNext()toPrevious()toLast()setCurrentIndex()来设置当前记录位置,显示相应数据

mapper->toFirst();

//信号、槽的机制modelviewmapper三个联系再一起

connect(view->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),

mapper, SLOT(setCurrentModelIndex(QModelIndex)));

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics