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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt + Postgresql (все под Windows) - SELECT не селектится...  (Прочитано 7136 раз)
yanis
Гость
« : Июнь 23, 2010, 16:33 »

Собственно сабж. Получаю пустой cmdUsers и 0 ошибок.

Код:
    QSqlError dbError;
    QSqlQuery query(db);
    bool queryRes;

    ui->cmbUsers->clear();
    queryRes = query.exec("SELECT \"lstUsers\".\"ID\", \"lstUsers\".\"UserName\", \"lstUsers\".\"RealName\" FROM public.\"lstUsers\" ORDER BY \"lstUsers\".\"RealName\" ASC;");
    if (queryRes) {
       // QMessageBox::critical(this, "Проверка связи", dbError.text(), QMessageBox::Close);
        while (query.next()) {
            ui->cmbUsers->addItem(query.value(2).toString());
        }
    }else{
        dbError = db.lastError();
        QMessageBox::critical(this, "Ошибка", dbError.text(), QMessageBox::Close);
    }

В табличке lstUsers содержится 4 записи.
Если приведенный запрос исполнять из pgAdmin'a - все работает.
Из qt соединение с БД устанавливается правильно, pgAdmin его показывает.
Включил в postgresql.conf log_statement=all - все вроде бы правильно
Цитировать
2010-06-23 10:46:38 GMTLOG: statement: select version()
2010-06-23 10:46:38 GMTLOG: statement: SET CLIENT_ENCODING TO 'UNICODE'
2010-06-23 10:46:38 GMTLOG: statement: SET DATESTYLE TO 'ISO'
2010-06-23 10:46:38 GMTLOG: statement: SELECT "lstUsers"."ID", "lstUsers"."UserName", "lstUsers"."RealName" FROM public."lstUsers" ORDER BY "lstUsers"."RealName" ASC;

Получается, программа вроде как запрос к серверу шлет, но не обрабатывает.
Какие причины могут быть, что комбобокс не заполняется? Или сервер как-то может возвращать пустой результат?

Запустил
C:\Qt\2010.02.1\qt\demos\sqlbrowser\release\sqlbrowser.exe

Драйвер в выпадающем списке отображается, соединение с БД устанавливается нормально, список таблиц отображается.
Однако:
1. При даблклике по таблице он говорит "Unable to find table "lstUsers"" (как и другие таблицы).
2. При щелчке правой кнопкой - Show schema - без ошибок, но таблица пустая.
3. Но!
SELECT "lstUsers"."ID", "lstUsers"."UserName", "lstUsers"."RealName" FROM public."lstUsers" ORDER BY "lstUsers"."RealName" ASC;
Корректный результат...

"На всякий случай" снес кьют, постгрес.
Поставил Постгрес, потом Кьют, откомпилировал плагин для PSQL.
Ничего не изменилось...

Куда дальше копать?
Записан
asvil
Гость
« Ответ #1 : Июнь 23, 2010, 16:54 »

Немного не в тему. Если comboBox не редактируемые лучше сделать так:
Код:
model = new QSqlQueryModel;
model.setQuery("select...", database);
if (model.lastError.isValid()) {
return error;
}
combo.setModel(model);
combo.setModelColumn(1);
Может это связано с использованием схемы. Может постгрес не настроен подставлять public если схема не указана.
Может пользователь из под которого производиться подключение не имеет доступа к таблице users.
Записан
yanis
Гость
« Ответ #2 : Июнь 23, 2010, 17:10 »

Немного не в тему. Если comboBox не редактируемые
...
Может это связано с использованием схемы. Может постгрес не настроен подставлять public если схема не указана.
Может пользователь из под которого производиться подключение не имеет доступа к таблице users.
Отлично работает, спасибо!

Теперь встречные вопросы:
А если комбо редактируемые (или другой контрол?)
Как настроить постгрес по-любому подставлять паблик?
А как сделать многоколоночный комбобокс?
« Последнее редактирование: Июнь 23, 2010, 17:12 от yanis » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #3 : Июнь 23, 2010, 17:19 »

Цитировать
Однако:
1. При даблклике по таблице он говорит "Unable to find table "lstUsers"" (как и другие таблицы).
2. При щелчке правой кнопкой - Show schema - без ошибок, но таблица пустая.
3. Но!
SELECT "lstUsers"."ID", "lstUsers"."UserName", "lstUsers"."RealName" FROM public."lstUsers" ORDER BY "lstUsers"."RealName" ASC;
Корректный результат...
это известный касяк, в Qt 4.3.x это работало, а потом исправили Qt и работать перестало Улыбающийся
Т.е. имена в разных регистрах перестали работать
эту демку можно исправить так:
Код
C++ (Qt)
QString tableName = "Foo"; // исходное имя
QSqlDriver *dr = QDatabase::database().driver();
tableName = dr->escapeIdentifier(tableName, QSqlDriver::TableName);
 
Записан

Юра.
yanis
Гость
« Ответ #4 : Июнь 23, 2010, 17:52 »

это известный касяк, в Qt 4.3.x это работало, а потом исправили Qt и работать перестало Улыбающийся
Т.е. имена в разных регистрах перестали работать
эту демку можно исправить так:
Код
C++ (Qt)
QString tableName = "Foo"; // исходное имя
QSqlDriver *dr = QDatabase::database().driver();
tableName = dr->escapeIdentifier(tableName, QSqlDriver::TableName);
 
Спасибо! Сейчас поковыряю демку. Если поправлю - может что и понимать начну Улыбающийся

Шайтанама, теперь и тут работает!
« Последнее редактирование: Июнь 23, 2010, 18:19 от yanis » Записан
asvil
Гость
« Ответ #5 : Июнь 23, 2010, 18:23 »

Цитировать
А если комбо редактируемые (или другой контрол?)
Для этого подойдет QSqlTableModel. Но далеко не сразу подойдет.
Цитировать
А как сделать многоколоночный комбобокс?
Код:
view = new QTableView(this);
combo.setView(view);
view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
  view->horizontalHeader()->setVisible(!d->hideHorizontalHeader);
  view->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  view->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  view->setAutoScroll(false);
  view->setColumnHidden(d->keyColumn, d->hideKeyColumn);
  view->setSelectionMode(QAbstractItemView::SingleSelection);
  view->setSelectionBehavior(QAbstractItemView::SelectRows);

  view->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
  view->verticalHeader()->setVisible(false);
  view->verticalHeader()->setDefaultSectionSize(20);
  int width = view->horizontalHeader()->length()
              + view->horizontalHeader()->offset() + 5; // про запас

  int height = view->verticalHeader()->length() +
               view->verticalHeader()->offset() + 10; // про запас
// Вычисляем размер экрана, на котором родительский виджет
  QRect screen = QApplication::desktop()->availableGeometry(combo);

  // Чтобы комбо бокс не приуменьшал таблицу
  view->setMinimumSize(qMin(width, screen.width() - 10), qMin(height, screen.height() - 10));

Все вышеперечисленное имеет некоторое количество подводных камней.
Записан
yanis
Гость
« Ответ #6 : Июнь 23, 2010, 21:35 »

Цитировать
А как сделать многоколоночный комбобокс?
Код:
...
view->horizontalHeader()->setVisible(!d->hideHorizontalHeader);
...

Все вышеперечисленное имеет некоторое количество подводных камней.

Сначала напугался многочисленных строк кода, нагуглился, окончательно запутался и решил скопипастить ваше.
Что такое d в коде?

Неужели нет более простого решения? Пока достаточно иметь колонку из БД в комбике и скрытую колонку (ИД строки) из таблицы в базе. Хоть городи второй невидимый комбик рядом, типа
Код:
ui->cmb1->setModel(model);
ui->cmb1->setModelColumn(2);
ui->cmb_id->setModel(model);
ui->cmb_id->setModelColumn(0);
Модель, надеюсь, можно использовать несколько раз?
Записан
asvil
Гость
« Ответ #7 : Июнь 23, 2010, 22:37 »

Прошу прощенья за копипаст из исходных текстов. d-> можно удалить. Вот псевдокод, чтобы увидеть результат.
Код:
view->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
  view->horizontalHeader()->setVisible(false);
  view->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  view->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  view->setAutoScroll(false);
  view->setSelectionMode(QAbstractItemView::SingleSelection);
  view->setSelectionBehavior(QAbstractItemView::SelectRows);

  view->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
  view->verticalHeader()->setVisible(false);
  view->verticalHeader()->setDefaultSectionSize(20);
  int width = view->horizontalHeader()->length()
              + view->horizontalHeader()->offset() + 5; // про запас

  int height = view->verticalHeader()->length() +
               view->verticalHeader()->offset() + 10; // про запас
// Вычисляем размер экрана, на котором родительский виджет
  QRect screen = QApplication::desktop()->availableGeometry(combo);

  // Чтобы комбо бокс не приуменьшал таблицу
  view->setMinimumSize(qMin(width, screen.width() - 10), qMin(height, screen.height() - 10));

Но лучше назовите задачу очень конкретно, потому что я в свое время заморочившись: "а что если комбобокс редактируемый", - потратил многовато времени, но не достиг нужного ГУИ результата.
Если я правильно понял, вы делаете будущее "окно входа"? Сделайте как в *nix или win:
QListView
и по QListView::onClick показывайте
QInputDialog::getString()
QListView выгоднее QComboBox ровно на один клик.
Если вы хотите сделать форму для редактирования списка пользователей/назначения прав и т.д.
Записан
yanis
Гость
« Ответ #8 : Июнь 25, 2010, 08:26 »

d-> можно удалить...
Повоевал немного с утра, хотел было завопить, что опять не работает - потом допер, что зря комментирую
Код:
combo.setModel(model);
А зачем добавлять ширину и высоту "про запас"? Я удалил "запасы" - ширина встала ровненько, может пиксель только справа лишний, а по высоте видно поле пикселя 3-4 внизу. Или на других платформах тейблВью рисуется по-другому?

Но лучше назовите задачу очень конкретно...
Если я правильно понял, вы делаете будущее "окно входа"?
Задач с комбобоксами 100500, в данном случае - это будет ридонли комбо со списком пользователей, для фильтрации таблицы со списком некоторых записей.

А вообще - хочу комбобокс как в МС Акцессах. Прямо в редакторе свойств накликать запрос, указать кол-во и размер колонок - и все работает Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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