Posts Tagged ‘Qt开发’

Qt下的QVariant类

September 12th, 2016

QVariant是一个数据类型类,存储不同类型的数据结构,一般情况下C++的class都不允许没有构造函数和析构函数存在。为了方便数据库对象存取,可以使用QVariant class。一个QVariant对象在一个时间内只保留一种类型的值。我们可以使用canConvert来查询是否能够转换当前的类型。转换类型一般以toT()命名。

QVariant可以保存很多Qt的数据类型,通过查看Document,可以知道发现支持很多Qt特定的数据类型,并且还有C++基本类型,如int、float等。QVariant还能保存很多集合类型,如QMap<QString, QVariant>, QStringList和QList<QVariant>等,因此QVariant完全满足现有编程需要。

今天在写代码过程中,尤其是读取数据库大量记录时,这个类足够好用。

struct s_field
{
      int type;
      QString fieldnum;
}
struct s_record
{
      QList<s_field> fieldlist;
      QString tableName;
}

struct s_recorddata
{
      QList<QVariant> datalist;
}
QList<s_recorddata> listdata;

通过这个数据结构我们可以把读到的数据放到listdata中,而每一个datalist都是一条记录,datalist中每一个的QVariant都是一个字段,我们不仅可以通过这个字段读取到数据,也可以判断具体的数据类型。

Type QVariant::type() const

Returns the storage type of the value stored in the variant. Although this function is declared as returning QVariant::Type, the return value should be interpreted as QMetaType::Type. In particular, QVariant::UserType is returned here only if the value is equal or greater than QMetaType::User.

Note that return values in the ranges QVariant::Char through QVariant::RegExp and QVariant::Font through QVariant::Transform correspond to the values in the ranges QMetaType::QChar through QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.

Pay particular attention when working with char and QChar variants. Note that there is no QVariant constructor specifically for type char, but there is one for QChar. For a variant of type QChar, this function returns QVariant::Char, which is the same as QMetaType::QChar, but for a variant of type char, this function returns QMetaType::Char, which is not the same as QVariant::Char.

Also note that the types void*, long, short, unsigned long, unsigned short, unsigned char, float, QObject*, and QWidget* are represented in QMetaType::Type but not in QVariant::Type, and they can be returned by this function. However, they are considered to be user defined types when tested against QVariant::Type.

To test whether an instance of QVariant contains a data type that is compatible with the data type you are interested in, use canConvert().

按照上面的数据结构和声明,只要listdata[i].datalist[j].type()就可以返回具体枚举类型,然后想返回具体值就是使用listdata[i].datalist[j].toInt() 或者其他的toxxx()即可。赋值的具体用法就是直接赋值即可。QVariant var; var = datatime …. var = 5 … var = 5.0 …

 

参考:

http://doc.qt.io/qt-4.8/qvariant.html#QVariant-2

Qt学习之路——XML Editor

September 22nd, 2013

接着刚才的Write XML来写。。。。。
这个Editor有界面,我使用MVC的方式,插入数据都通过QStandardItem来插入,这个model都是tree view,通过QDomDocument里面的setContent()方法导入。然后就是通过firstChildElement来找到root节点,然后开始下面的工作。
XML数据与上一节内容相同,这里不再赘述。

XML读写流程 QDomElement -> QDomNodeList -> toElement ->…..

QDomElement xmlroot = document.firstChildElement();
QDomNodeList books = xmlroot.elementsByTagName("Book");
QDomElement book = books.at(i).toElement();
QDomNodeList chapters = book.elementsByTagName("Chapter");
QDomElement chapter = chapters.at(h).toElement();

其实感觉tree view model插入方式和QDomDocument方式很类似,都是要找到root节点,才能向后插入
model层级关系:root->bookitem->chapteritem

void Dialog::ReadFile()
{
    QStandardItem *root = new QStandardItem("Books");
    model->appendRow(root);

    QDomDocument document;
    QFile file(FileName);
    if(file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        document.setContent(&file);
        file.close();
    }

    QDomElement xmlroot = document.firstChildElement();

    QDomNodeList books = xmlroot.elementsByTagName("Book");//通过root我找到child节点Book

    for(int i =0;i<books.count();i++)
    {
        QDomElement book = books.at(i).toElement();
        QStandardItem *bookitem = new QStandardItem(book.attribute("Name"));

        QDomNodeList chapters = book.elementsByTagName("Chapter");
        for(int h= 0;h<chapters.count();h++)
        {
            QDomElement chapter = chapters.at(h).toElement();
            QStandardItem *chapteritem = new QStandardItem(chapter.attribute("Name"));
            bookitem->appendRow(chapteritem);
        }
        root->appendRow(bookitem);

    }
}

void Dialog::WriteFIle()
//写的原理和读其实很类似,,他是从model中获取item而已,然后回复这个xml节点信息。
{

    QDomDocument document ;

    QDomElement xmlroot = document.createElement("Books");
    document.appendChild(xmlroot);

    QStandardItem *root = model->item(0,0);
    for(int i= 0;i < root->rowCount();i++)
    {
        QStandardItem *book = root->child(i,0);

        QDomElement xmlbook = document.createElement("Book");
        xmlroot.appendChild(xmlbook);

        xmlbook.setAttribute("Name",book->text());
        xmlbook.setAttribute("ID",i);


        for(int h =0 ;h< book->rowCount();h++)
        {
            QStandardItem *chapter = book->child(h,0);
            QDomElement xmlchapter = document.createElement("Chapter");
            xmlchapter.setAttribute("Name",chapter->text());
            xmlchapter.setAttribute("ID",h);
            xmlbook.appendChild(xmlchapter);
        }
    }

//    QFile file(FileName);
    QFile file("/home/lzz/test.xml");
    if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug() << "Failed to write file";
    }
    QTextStream stream(&file);
    stream << document.toString();
    file.close();


    qDebug() << "Finished!!!";
}

2013-09-22 21:26:36的屏幕截图

Qt学习之路——Read XML with DOM

September 22nd, 2013

接着昨天的来讲写XML来讲,最大的问题就是要分清root与children节点。要知道你是在哪个节点操作的,是子节点还是父节点。
然后配合使用API来解析就可以了。我们要知道Tag就是<>中的属性。attribute就是属性值。 » Read more: Qt学习之路——Read XML with DOM

在Qt中编写XML文件

September 21st, 2013

对于XML文件,大家应该都会太陌生,只要定义好了XML的格式,我们就可以用来传送数据了。
XML本身没有什么表示,他不像HTML那样表现数据,每个Node也没有什么具体的含义,全部靠编程者自己定义。 » Read more: 在Qt中编写XML文件

基于Qt Framework的QNotead

September 21st, 2013

今天是中秋的第三天。闲来无事所以编了个QNotePad

由于Qt为我们我们提供了大量优质的API,所以我们只要学习了解了这些函数,就可以快速开发出一款属于自己的note++

这个东西的精髓在于Open Save SaveAs的处理。

我们可以使用QTextEdit空间,然后配合QTextStream使用.
另外我们要主要的一点就是Qt中reasource的使用。我们要先建立资源文件,然后倒入resource,最后在qt designer中加载 图标。 除此之外就是menubar的使用。我们可以把菜单中的图标放在menubar中,这样可以方便操作。

Key Code:

void MainWindow::on_actionOpen_triggered()
{
    QString file = QFileDialog::getOpenFileName(this,"Open a file");

    if(!file.isEmpty())
    {
        QFile mFile(file);
        if(mFile.open(QFile::ReadOnly | QFile::Text))
        {
            mFileName = file;
             this->setWindowTitle(mFileName);
            QTextStream in(&mFile);
            QString text = in.readAll();

            mFile.close();

            ui->textEdit->setPlainText(text);

        }
    }
}

void MainWindow::on_actionSave_triggered()
{
    QFile mFile(mFileName);
    if(mFile.open(QFile::WriteOnly | QFile::Text))
    {
        QTextStream out(&mFile);
        this->setWindowTitle(mFileName);
        out << ui->textEdit->toPlainText();

        mFile.flush();
        mFile.close();
    }
}

void MainWindow::on_actionSave_As_triggered()
{
    QString file = QFileDialog::getSaveFileName(this,"Save a file");
    if(!file.isEmpty())
    {
        mFileName = file;
        on_actionSave_triggered();
    }
}

2013-09-21 16:10:24的屏幕截图

DOT