Иерархия QTreeWidgetItem для SQL - PullRequest
0 голосов
/ 22 января 2019

Я хотел бы сохранить содержимое QTreeWidget в базе данных MySQL.

SQL для описания таблицы:

CREATE TABLE category (
id          int not null,
parentId    int,
name        varchar(1024), );

Где parentId равновнешний ключ, который ссылается на id из той же таблицы.(предназначено для самостоятельного объединения)

Используя QtCreator, следующий код работает нормально:

int FactsBuilder::findChildren( QTreeWidgetItem *node, int top )
{

    for( int i = 0; i < node->childCount(); ++i )
    {

       QTreeWidgetItem *item = node->child(i);
       qDebug() << "Child: " << top++ << " - "  << item->text(0);
       if(item->childCount() > 0 ) {

           this->findChildren(item, top++ );
       }
    }

    return top;
}

void FactsBuilder::updateCatSQL()
{

    int count = 1;
    for( int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i )
    {

       QTreeWidgetItem *item = ui->treeWidget->topLevelItem( i );
       qDebug() << "Item Number: " << count++ <<  " - " << item->text(0);


       if(item->childCount() > 0 ) {
            count = this->findChildren( item, count);
       }
    }
}

пример вывода:

Top:  1  -  "foo"
Top:  2  -  "bar"
Child:  3  -  "beer"
Child:  4  -  "ice"
Top:  5  -  "bla"
Top:  6  -  "baz"

У верхних элементов нетparent, поэтому в таком случае столбец parentId в базе данных MySQL будет содержать NULL.

В этом случае QTreeWidgetItems с "beer" и "ice", хранящимися в его текстовом атрибуте, приведет кпри сохранении «2» в столбце parentId базы данных.Потому что они организованы в QTreeWidgetItem с «баром», хранящимся в его текстовом атрибуте.

Первый регистр

За исключением случаев, когда QTreeWidgetItems со «ice» будеторганизованный в QTreeWidgetItem с «пивом», хранящимся в его текстовом атрибуте.

В таком случае я бы ожидал «2» и «3» в столбцах parentId базы данных.

Второй случай

1 Ответ

0 голосов
/ 22 января 2019

Прежде всего, если ваша таблица лучше спроектирована, решение упрощается, лучше сделать поле id с автоинкрементом:

CREATE TABLE IF NOT EXISTS category  (
    id          int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    parentId    int,
    name        varchar(1024)
)

Затем я создал метод, который получает invisibleRootItem() от QTreeWidget и сохраняет информацию в базе данных.

#include <QtWidgets>
#include <QtSql>

static bool createConnection(){
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("hostname");
    db.setDatabaseName("databasename");
    db.setUserName("username");
    db.setPassword("password");
    if (!db.open()) {
        qDebug()<<"Cannot open database\n"
                  "Unable to establish a database connection.\n"
                  "This example needs SQLite support. Please read "
                  "the Qt SQL driver documentation for information how "
                  "to build it.\n\n"
                  "Click Cancel to exit.";
        return false;
    }
    QSqlQuery query;
    query.exec("DROP TABLE IF EXISTS category;");
    if(!query.exec(R"(CREATE TABLE IF NOT EXISTS category  (
                   id          int NOT NULL AUTO_INCREMENT PRIMARY KEY,
                   parentId    int,
                   name        varchar(1024)
                   ))"))
        qDebug()<<query.lastError().text();
    return true;
}
static void fill_model(QTreeWidget &tree){
    QTreeWidgetItem *foo_item = new QTreeWidgetItem({"foo"});
    QTreeWidgetItem *bar_item = new QTreeWidgetItem({"bar"});
    QTreeWidgetItem *bla_item = new QTreeWidgetItem({"bla"});
    QTreeWidgetItem *baz_item = new QTreeWidgetItem({"baz"});
    for(QTreeWidgetItem *item : {foo_item, bar_item, bla_item, baz_item})
        tree.addTopLevelItem(item);
    QTreeWidgetItem *beer_item = new QTreeWidgetItem({"beer"});
    QTreeWidgetItem *beer_child_item = new QTreeWidgetItem({"beer_child"});
    QTreeWidgetItem *ice_item = new QTreeWidgetItem({"ice"});
    for(QTreeWidgetItem *item : {beer_item, ice_item})
        bar_item->addChild(item);
    beer_item->addChild(beer_child_item);
    beer_child_item->addChild(new QTreeWidgetItem({"beer_child_child"}));
}
static void save_to_db(const QString & tablename, QTreeWidgetItem* parent, int parent_id=0){
    for(int i=0; i< parent->childCount(); ++i){
        QTreeWidgetItem *child_item = parent->child(i);
        QSqlQuery query(QString("INSERT INTO %1 (parentId, name) VALUES (?, ?)").arg(tablename));
        if(parent_id != 0)
            query.bindValue(0, parent_id);
        query.bindValue(1, child_item->text(0));
        if(!query.exec())
            qDebug()<< query.lastError().text();
        save_to_db(tablename, child_item, query.lastInsertId().toInt());
    }
}
int main(int argc, char *argv[]){
    QApplication a(argc, argv);
    if(!createConnection())
       return -1;
    QWidget w;
    QTreeWidget tree_widget;
    fill_model(tree_widget);
    save_to_db("category", tree_widget.invisibleRootItem());
    tree_widget.expandAll();
    QTableView table_view;
    QSqlTableModel model;
    model.setTable("category");
    model.select();
    table_view.setModel(&model);
    QHBoxLayout *hlay = new QHBoxLayout(&w);
    hlay->addWidget(&tree_widget);
    hlay->addWidget(&table_view);
    w.resize(640, 480);
    w.show();
    return a.exec();
}

enter image description here

...