Qt开发中遇到的问题

        新项目又快开始了,一个项目一种语言,这酸爽,真是本屌程序猿才能体会的啊。这次使用Qt,尼玛对于本屌这种一直使用Java,C++基础薄弱的程序猿来说还是有点难度,毕竟C++与Java、C#还是有些差别,一时半会儿还得适应。项目还没开始,在学习Qt的过程中自己构想几个例子来试手,也把使用过程中碰到的问题记录下来,可能都是一些非常非常基础的知识了(大虾莫喷,有好的方法请不吝赐教),但对于我这种没C++经验的程序猿还是要花一时半会儿才能解决,先把这些问题和解决方法都记录下来,供以后查阅吧。

1、使用QSqlQuery的bindValue方法编译出错,报no matching function for call to 'QSqlQuery::bindValue(const char [6], QString)'

报错代码:query.bindValue(":type", "类型");

看了书上的例子和Qt文档中的例子都是这样写的啊,语法没有错误啊。搞了半天原来是bindValue的第二个参数QVariant类型,cpp文件中没有QVariant的引用,

把#include <QVariant>加上就ok了,经验值加1,以后碰到这种问题就有经验处理了。

2、 出现field 'm_createDate' has incomplete type错误。

报错代码:头文件声明QDateTime m_createDate;出错

        报未完成的类型错误,由于只在头文件中加了class声明,如class QDateTime,在cpp文件中也使用#include <QDateTime>将该类引入,但由于使用QDateTime m_createDate;方式为创建了QDateTime对象,但由于只是对QDateTime类进行了声明而隐藏了类的实现,此时编译时不知道QDateTime的完成实现所以无法创建QDateTime对象。

解决办法有两种:

(1)在头文件中使用#include <QDateTime>方式替换class QDateTime;

(2)将QDateTime m_createDate;改为QDateTime *m_createDate;然后在构造函数中初始化该指针,在析构函数中删除该指针。使用指针的方式创建该对象的指向地址,而地址为数值所以无需知道QDateTime的完整实现。

3、QT绘图抗锯齿设置

QT中对于绘图抗锯齿的设置使用QPainter的setRenderHint()方法,具体设置为

painter->setRenderHint(QPainter::Antialiasing);

4、error: jump to case label case CData::INT:

      error:   crosses initialization of 'QByteArray array'
在使用switch语句时,编译时出现以上错误提示未初始化array变量。但是在case分支中对array进行了初始化,如下代码:

switch(type)
        {
        case CData::BYTEARRAY:
            QByteArray array;
            break;
        case CData::INT:
            qDebug() << "key:"<< it.key() << ",value:" << it.value()->getInt();
            break;
        }
修改代码,将array变量的定义放在switch外部即可。

5、编译时遇到*** No rule to make target 'xxx.cpp', needed by 'debug/xxx.o'. Stop.问题

        出现该问题的原因为,在.pro文件中包含了某.cpp文件和.h文件,但是在项目中可能因为该文件未被使用,在本地直接删掉了该文件,而.pro文件中还包含了这两个文件的引用,此时编译就会出现以上问题。解决办法是在.pro文件中删除“xxx.cpp”和“xxx.h”的引用即可。

6、C++中求数组长度

        在C++中没有包含对数组求长度的函数,只提供了一个strlen用于求字符串长度的函数。如果需要对其他类型的数组求长度,需采用如下方法:

int length = sizeof(array) / sizeof(array[0])
这里的array为任意类型的数组。

7、调用自定义的库,编译时出现:undefined reference to `_imp___ZN10CConverter10byteToCharE10QByteArray'

        今天在调用自己写的库,编译时出现标题的错误提示,大概含义是CConverter类中未找到byteToChar的实现。找了半天,原来是.cpp文件中该方法前忘了加“CConverter::”,真是折腾了半天。记下,再不要这么粗心大意!

8、error: '>>' should be '> >' within a nested template argument list QMap<QString, QList<CProtocolDom>> *m_protocolMap;

        QT中在定义列表或map中嵌套列表或map时,需要注意的是,两个尖括号之间需要加上一个空格,否则编译就出现如题所述错误。
QMap<QString, QList<CProtocolDom>> *m_protocolMap; //错误代码

QMap<QString, QList<CProtocolDom> > *m_protocolMap; //正确代码
                                 ^增加了一个空格

9、C++中对类型的判断

        在C++中对对象类型的判断使用typeid运算符,相当于java中instanceof关键字。但用法不一样。typeid表达式形式为typeid(e),其中e可以是任意表达式或类型名字。typeid操作的结果是一个常量对象的引用,该对象的类型是标准库类型type_info或者type_info的共有派生类型。type_info类定义在typeinfo头文件中,所以在使用typeid运算符时需要将typeinfo头文件引入程序中。

使用方法示例:

CData data;
bool is = typeid(data) == typeid(CData);

// is = true

CData* data = new CData;
bool is = typeid(data) == typeid(CData);

//这样输出永远为false,因为data是一个地址,typeid是作用于对象。正确做法为如下代码:

CData* data = new CData;
bool is = typeid(*data) == typeid(CData);

10、关于QT中容器元素的内存释放问题

在编程中很多时候会使用到容器(如QMap、QList)来存放自己所需的数据,这里就涉及到对容器中存储的数据的内存释放问题。这里测试了几行代码,留下来方便以后的查看和理解。

第一种情况,容器中存放的为new出来的数据,需手动释放其内存

    QMap<QString, CTestClass*>* map = new QMap<QString, CTestClass*>;
    CTestClass* tc1 = new CTestClass;
    CTestClass* tc2 = new CTestClass;
    CTestClass* tc3 = new CTestClass;
    map->insert("1", tc1);
    map->insert("2", tc2);
    map->insert("3", tc3);
    delete map;//这样只能释放掉map,而map中的CTestClass并不能得到释放

    QList<CTestClass*>* list = new QList<CTestClass*>;
    CTestClass *item1 = new CTestClass;
    CTestClass *item2 = new CTestClass;
    CTestClass *item3 = new CTestClass;
    list->append(item1);
    list->append(item2);
    list->append(item3);
    delete list;//这样只能释放掉list的内存,而list中的CTestClass也不能得到释放

第二种情况,容器中存放的为数据对象,这些对象的内存由容器统一管理,当对象脱离了容器或容器释放时,容器内的对象内存也得到相应的释放

    QMap<QString, CTestClass>* map_1 = new QMap<QString, CTestClass>;
    CTestClass tc1_1;
    CTestClass tc2_1;
    CTestClass tc3_1;
    map_1->insert("1", tc1_1);
    map_1->insert("2", tc2_1);
    map_1->insert("3", tc3_1);
    delete map_1;//释放map_1、map->remove("1")或map->clear(),map中的对象内存都会得到释放

    QList<CTestClass>* list_1 = new QList<CTestClass>;
    CTestClass item1_1;
    CTestClass item2_1;
    CTestClass item3_1;
    list_1->append(item1_1);
    list_1->append(item2_1);
    list_1->append(item3_1);
    delete list_1;
CTestClass类:

#include <QDebug>
#include "ctestclass.h"

CTestClass::CTestClass()
{
}

CTestClass::~CTestClass()
{
    qDebug() << "delete CTestClass!";
}

11、释放未初始化指针

        在程序中一定不能释放未初始化的指针,否则会出错。在程序中,声明一个指针变量,而不给他做初始化工作,在delete时使用if(m_prt){},if语句中的语句是会被执行的,如果在if语句中delete m_prt,程序会崩溃,因为程序在运行时会为m_prt初始化一个指向不明内存的地址,当删除这个地址时就出现错误。

12、new int[10]和new int[10]()的区别

int * arr1 = new int[10];        //创建一个数组,但并未给数组中的元素初始化,数组中各值为随机数。
int * arr2 = new int[10]();     //创建一个数组,并将其数组中的各个值初始化为0

12、LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

使用MSVC编译器编译项目时出现:LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

可能出现问题的原因:在项目中包含了其他库,而这些库是release版本的,在使用qt构建时使用的debug模式,这样就出现了如题所示的编译错误,将模式切换成release版本就没有问题了




  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值