Russian Qt Forum
Сентябрь 30, 2024, 14:35 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [Решено] SQL + Model + Tree?  (Прочитано 10703 раз)
CL0NE
Гость
« : Сентябрь 27, 2010, 22:24 »

Дано:
база данных с несколькими двумя таблицами вида
A
id
id_b
text
B
id
parent
text

Что нужно получить:
дерево, являющееся обьединением этих двух таблиц
[-]Text A 1
[-]Text B 1
[-]Text B 2
[-]Text B 3
[-]Text A 2
[-]Text B 4
...

Вариации:
а) Извлечь через QSqlQuery данные и вручную заполнить  QStandardItemModel или даже QTreeWidget (здесь вроде бы вопросов у меня не возникает, но решение кажется несколько корявым что ли)
б) Писать свою QSqlTreeModel.
в) Написать свою proxy-модель (найдено как совет на аналогичный вопрос гуглом)

Суть вопроса:
Нужна помощь знающих людей в том как это реализовать и какие есть еще вариации. Я вовсе не прошу, чтобы за меня это кто-то сделал, мне всего лишь нужен толчок в нужную сторону..
« Последнее редактирование: Октябрь 05, 2010, 23:23 от CL0NE » Записан
crossly
Гость
« Ответ #1 : Сентябрь 27, 2010, 22:55 »

поиск тебе под зад... Улыбающийся (сори за возможно не уместный юмор)... но на самом деле... тема на этом форуме уже десяток раз подымалась... Улыбающийся
Записан
CL0NE
Гость
« Ответ #2 : Сентябрь 27, 2010, 23:19 »

Тут еще загвоздка, как цеплять выборку из первой таблицы к другой, ведь данные там различаются (потому и две таблицы)

зы. хотя возможно поторопился с созданием темы...
« Последнее редактирование: Сентябрь 27, 2010, 23:27 от CL0NE » Записан
CroCIV
Гость
« Ответ #3 : Сентябрь 28, 2010, 07:19 »

А зачем тебе id_b в таблице А?
Записан
CroCIV
Гость
« Ответ #4 : Сентябрь 28, 2010, 07:48 »

Например вот так.. дерево будет строиться по частям по мере необходимости новой ветки...
Не компилировал, возможны дуратские ошибки
Код:
void <НазваниеТвоегоКласса>::<НазваниеТвоегоСлота1>() //думаю это будет слот, чтоб была возможность обновлять дерево (вдруг у тебя программа будет многопользовательская)
{
disconnect(ui.treeWidget,SIGNAL(itemExpanded(QTreeWidgetItem *)),this,SLOT(<НазваниеТвоегоСлота2>(QTreeWidgetItem *)));
ui.treeWidget->clear();
QSqlQueryModel *sql = new QSqlQueryModel(this);
sql->setQuery("select distinct text, id_b, id from A order by text",QSqlDatabase::database());
if (sql->lastError().isValid())
QMessageBox::warning(this, "Соединение с SQL-сервером","Обнаружена ошибка соединения:\n"+sql->lastError().text(),QMessageBox::Ok);
else
{
ui.treeWidget->setColumnCount(3);
ui.treeWidget->setColumnHidden(1,true);
ui.treeWidget->setColumnHidden(2,true);
QStringList sl;
sl<<"Название"<<"PKeyB"<<"PKeyA";
ui.treeWidget->setHeaderLabels(sl);
for (int j=0; j<sql->rowCount(); j++)
{
QTreeWidgetItem *twihead = new QTreeWidgetItem(ui.treeWidget);
for (int i=0; i<ui.treeWidget->columnCount(); i++)
{
twihead->setText(i, sql->record(j).value(i).toString());
if (!twihead->text(1).isEmpty())
twihead->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
}
}
}
for (int i=0; i<ui.treeWidget->columnCount(); i++)
ui.treeWidget->resizeColumnToContents(i);
connect(ui.treeWidget,SIGNAL(itemExpanded(QTreeWidgetItem *)),this,SLOT(<НазваниеТвоегоСлота2>(QTreeWidgetItem *)));
}

Код:
void <НазваниеТвоегоКласса>::<НазваниеТвоегоСлота2>(QTreeWidgetItem *twi)
{
if (twi->childCount()==0)
{
QSqlQueryModel *sql = new QSqlQueryModel(this);
sql->setQuery("select distinct t1.text, t1.id, case when t2.id is null then '0' else '1' end from B t1 left join B t2 on t2.parent = t1.id where t1.parent = "+twi->text(1)+" order by t1.text",QSqlDatabase::database());
if (sql->lastError().isValid())
QMessageBox::warning(this, "Соединение с SQL-сервером","Обнаружена ошибка соединения:\n"+sql->lastError().text(),QMessageBox::Ok);
else
{
for (int i=0; i<sql->rowCount(); i++)
{
QTreeWidgetItem *twic = new QTreeWidgetItem(twi);
for (int j=0; j<2; j++)
twic->setText(j, sql->record(i).value(j).toString());
if (sql->record(i).value(2).toBool())
twic->setChildIndicatorPolicy (QTreeWidgetItem::ShowIndicator);
}
}
}
ui.treeWidget->resizeColumnToContents(0);
}
« Последнее редактирование: Сентябрь 29, 2010, 08:53 от CroCIV » Записан
Karl-Philipp
Гость
« Ответ #5 : Сентябрь 28, 2010, 12:23 »

>>Толчок в нужную сторону
http://qt-apps.org/content/show.php/QyurSqlTreeView?content=114372
+ поиск по форуму: тема не единажды подымалась и были конкретные решения.
Записан
CL0NE
Гость
« Ответ #6 : Сентябрь 28, 2010, 18:06 »

А зачем тебе id_b в таблице А?
Как я написал уже выше, таблицы различаются (просто приведенный пример - упрощен, т.к. не существенно), но единственная связь - тот самый id_b, и нужно, используя данную связь, отобразить соответствующую иерархию Улыбающийся

А пока что я задействовал поиск и открыто с десяток вкладок, надо бы перечитать все Улыбающийся Ежели окажусь слишком туп - буду дальше донимать вопросами в этой теме ^^
Записан
CroCIV
Гость
« Ответ #7 : Сентябрь 29, 2010, 08:39 »

Как я написал уже выше, таблицы различаются (просто приведенный пример - упрощен, т.к. не существенно), но единственная связь - тот самый id_b, и нужно, используя данную связь, отобразить соответствующую иерархию Улыбающийся

тогда тут три варианта: либо А.id не будет уникальным, либо у каждого А.id может быть только по одному потомку, либо нужно создавать таблицу АВ с полями id_a и id_b, которая свяжет множество потомков таблицы В с одной записью таблицы А.

Щас пример свой поправлю для случая, когда А.id является уникальным, а единственный потомок этой записи указан в поле A.id_b

Попробуй разобраться с этим примером он как раз под твою предметную область адаптирован
« Последнее редактирование: Сентябрь 29, 2010, 08:54 от CroCIV » Записан
CL0NE
Гость
« Ответ #8 : Сентябрь 29, 2010, 22:01 »

Цитировать
у каждого А.id может быть только по одному потомку
именно
Цитировать
пробуй разобраться с этим примером он как раз под твою предметную область адаптирован
спасибо, курим пока потихоньку все, что насобирали:)
Записан
RedDog
Гость
« Ответ #9 : Сентябрь 29, 2010, 23:10 »

Вот тут мой алгоритм составления дерева из БД. Работает очень шустро, и требуется всего один запрос к БД в самом начале. Можно на его основе заполнять модель, которую потом привязывать к TreeView, т.е. заточить под MVC
Записан
CroCIV
Гость
« Ответ #10 : Октябрь 01, 2010, 13:01 »

Вот тут мой алгоритм составления дерева из БД. Работает очень шустро, и требуется всего один запрос к БД в самом начале. Можно на его основе заполнять модель, которую потом привязывать к TreeView, т.е. заточить под MVC

а если у вас таблица имеет, скажем, "стопитьсот" записей, а мне нужно только одну вершинку второго уровня? а если у вас "стопитьсот" пользователей подключаются к вашей бд и все делают
SELECT * FROM nodes ORDER BY parentid по "стапитьсот" записям, и всем нужно только по одной вершинке первого-второго уровня?  Строит глазки
Записан
RedDog
Гость
« Ответ #11 : Октябрь 01, 2010, 14:45 »

а если у вас таблица имеет, скажем, "стопитьсот" записей, а мне нужно только одну вершинку второго уровня? а если у вас "стопитьсот" пользователей подключаются к вашей бд и все делают
SELECT * FROM nodes ORDER BY parentid по "стапитьсот" записям, и всем нужно только по одной вершинке первого-второго уровня?  Строит глазки
в очень многопользовательском режиме не тестил, но 10-20 юзеров работали с количеством ~ 100 тыс. записей, нагрузка на сервер незначительная, да и вопрос тогда стоял в том что бы как можно быстрее нарисовать полное дерево. С рекурсией это было в десятки раз дольше и нагрузка на сервер возрастала.
Записан
CL0NE
Гость
« Ответ #12 : Октябрь 05, 2010, 23:20 »

Если кому интересно:
После продолжительного чтения форума/документации, от использования TreeWidget/StandardItemModel я отказался и выбрал второй пункт - своя модель.
Основная идея реализации получилась похожей на реализацию Sergeich'a, в результате используется измененный под свои нужды код из сообщения http://www.prog.org.ru/index.php?topic=8028.msg42804#msg42804

Всем огромное спасибо Улыбающийся
« Последнее редактирование: Октябрь 05, 2010, 23:22 от CL0NE » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.053 секунд. Запросов: 21.