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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Сразу несколько таблиц с данными на одной форме  (Прочитано 9690 раз)
chester
Гость
« : Ноябрь 11, 2011, 09:16 »

Приветствую всех!!!
Я только начинаю работать с БД. Отображаю содержимое таблиц с помощью с помощью QTableModel -> QTableView. На одной форме у меня отображаются сразу 3 таблицы с данными. И при этом замечаются небольшие тормоза, например при вызове сообщения оно прорисовывается с задержкой. Когда QTableView без данных все отлично работает. Или, если только одна таблица заполнена данными, то тоже нормально работает.
Записан
chester
Гость
« Ответ #1 : Ноябрь 11, 2011, 14:04 »

если я вызываю перед выводом сообщения
Код
C
qApp->processEvents();
 
то оно прям быстро отрисовывается. Только вот насколько это правильно использовать это при каждом вызове сообщения
Записан
chester
Гость
« Ответ #2 : Ноябрь 14, 2011, 08:42 »

Подскажите пожалуйста, постоянный вызов:
Код
C
qApp->processEvents();
 
каждый раз при вызове диалога или сообщения ни к каким последствиям не приведет??
Просто я недавно занимаюсь QT, поэтому заранее извиняюсь возможно за глупые вопросы
Записан
Whiplash
Гость
« Ответ #3 : Ноябрь 14, 2011, 13:52 »

А что за сообщение?
Без кода трудно что-либо сказать.
Записан
chester
Гость
« Ответ #4 : Ноябрь 15, 2011, 07:27 »

Вот текст программы

Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QSqlError>
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   createConnection();
 
   table1 = new QSqlTableModel(this);
   table1 -> setTable("sprUnGroup");
   table1 -> select();
   ui->tableView -> setModel(table1);
 
   table2 = new QSqlTableModel(this);
   table2 -> setTable("sprGroup");
   table2 -> select();
   ui->tableView_2->setModel(table2);
 
   table3 = new QSqlTableModel(this);
   table3 -> setTable("spr");
   table3->select();
   ui->tableView_3->setModel(table3);
   ui->tableView_3->setCornerButtonEnabled(true);
 
   connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slotClick()));
}
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
void MainWindow::changeEvent(QEvent *e)
{
   QMainWindow::changeEvent(e);
   switch (e->type()) {
   case QEvent::LanguageChange:
       ui->retranslateUi(this);
       break;
   default:
       break;
   }
}
 
void MainWindow::createConnection()
{
   db = QSqlDatabase::addDatabase("QODBC");
   db.setDatabaseName("DRIVER={SQL Server};SERVER=SRVSQL;Database=oms_nsi;Trusted_Connection=Yes;");
   if(!db.open())
     QMessageBox::critical(this,tr("Ошибка"),tr("Невозможно подключиться к базе данных\n") + db.lastError().text());
}
 
void MainWindow::slotClick(){
   qApp->processEvents();
   QMessageBox::question(0,"Вы уверены","Вы действительно хотите удалить запись?");
}
 
Записан
Bepec
Гость
« Ответ #5 : Ноябрь 15, 2011, 14:49 »

Уважаемый Борис.
Давайте я вам объясню что вы делаете:

Форма загружается, прорисовывается и ... ждет когда окончатся функции, описанные в конструкторе. У вас в данном случае запрос к БД, который кстати может быть и более длительным(до 10-15 секунд), в зависимости от расположения базы, ее величины и величины канала связи.

Это плохо! Очень плохо.

Мой вариант (мб и не очень простой):

Код:
Ваш_Класс::Конструктор
{
    //  прописываем все ui методы (создание кнопок, формы, настройка их)
    // далее создаем поток загрузки (потомок от QThread в моем случае)
    LoadThread * thread = new QThread();
}

В самом же потоке вы вызываете все свои запросы, и передаете данные в основной поток (при этом интерфейс не виснет, пользователь видит программу с пустыми полями).

Получаете данные из потока, устанавливаете в View, показывая их пользователю. Пользователю так же можно вывести что-то типа  "Запрос к базам данных выполняется бззз...".

Дополнительная форма у вас я думаю работает аналогично ( в конструктор Вы все запихали). Потому и метод решения тот же.

PS по опыту знаю, лучше пользователь видит пустые поля с сообщением о загрузке сразу, чем видит тормоза при загрузке и думает, что тормозит ВАША программа, а не БД.


Добавлю - вызов processEvent  плох по 2 причинам
1) интерфейс все же тормозится и нервирует пользователя.
2) если же в моменты тормоза потыркать мышкой, полупить по клавиатуре и повазюкать экранчиком, то вполне возможен и завис/лаг/вылет/постоянный тормоз программы.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Ноябрь 15, 2011, 15:05 »

Подскажите пожалуйста, постоянный вызов:
Код
C
qApp->processEvents();
 
каждый раз при вызове диалога или сообщения ни к каким последствиям не приведет??
Не приведёт.

Добавлю - вызов processEvent  плох по 2 причинам
1) интерфейс все же тормозится и нервирует пользователя.
2) если же в моменты тормоза потыркать мышкой, полупить по клавиатуре и повазюкать экранчиком, то вполне возможен и завис/лаг/вылет/постоянный тормоз программы.
Интересно, как на эти пункты может повлиять вызов processEvent()?
« Последнее редактирование: Ноябрь 15, 2011, 15:08 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #7 : Ноябрь 15, 2011, 15:47 »

Неправильное место для processEvent() = ужасные тормоза.

Очередь забивается в течении 2-3 секунд, после чего тормоза я тебе гарантирую на протяжении последующей минуты, если оставить ее в покое.

И добивающее фаталити - слишком частый вызов Улыбающийся тормозит не так жестоко, но при выводе текста он начинает скакать и соответственно окошко тоже тормозит )
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Ноябрь 15, 2011, 17:03 »

Неправильное место для processEvent() = ужасные тормоза.

Очередь забивается в течении 2-3 секунд, после чего тормоза я тебе гарантирую на протяжении последующей минуты, если оставить ее в покое.

И добивающее фаталити - слишком частый вызов Улыбающийся тормозит не так жестоко, но при выводе текста он начинает скакать и соответственно окошко тоже тормозит )
Хм, действительно какие-то ужасы... Может проблема не в processEvent(), а в чём-то другом, например, в дизайне? Улыбающийся
Записан

Qt 5.11/4.8.7 (X11/Win)
chester
Гость
« Ответ #9 : Ноябрь 16, 2011, 07:22 »

Спасибо, что ответили!!! У меня пока использование processEvent() не приводит ни к каким тормозам, а даже наоборот сообщение вылазиет мгновенно ... без его использования, при вызове сообщения прям видно как оно прорисовывается. Я же так понимаю эта функция выполняет все события и вызывает сообщение, а уже после вызова сообщения она перестает действовать и события выполняются в обычном порядке?
Записан
Bepec
Гость
« Ответ #10 : Ноябрь 22, 2011, 09:27 »

Она обрабатывает все события в очереди. т.е. все твои движения мышкой, отрисовка виджета. ждет пока действия выполнятся и далее продолжает программу(функцию).
Записан
chester
Гость
« Ответ #11 : Ноябрь 25, 2011, 08:07 »

Она обрабатывает все события в очереди. т.е. все твои движения мышкой, отрисовка виджета. ждет пока действия выполнятся и далее продолжает программу(функцию).
Спасибо за разъяснения!!! У меня тут еще один вопросик созрел, не буду новую тему создавать - сдеся спрошу ... при использовании функции resizeRowsToContents(), данные из базы грузятся заметно медленне и это при не очень большом кол-ве строк 250 где-то. И вот хочу спросить нормально ли это и возможно можно ли как-то избежать этого.
Записан
Bepec
Гость
« Ответ #12 : Ноябрь 25, 2011, 08:57 »

Отвечаю - нужно по делу создавать новую тему, дабы мудрость моя и прочая могла быть найдена по теме Resize Rows Contents.

Отвечаю - эта функция ресайзит ВСЕ строки одновременно. Т.е. расчет содержимого, расчет нужного места и все все все.

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

то применяй при каждом добавлении строки resizeRowToContents(int номер строки). (заметь там будет ресайзиться 1 строка, а при вызове Rows будут все).

PS то же в 3 словах - Ты сейчас ломаешь веник, а нужно по прутику Улыбающийся
Записан
chester
Гость
« Ответ #13 : Ноябрь 25, 2011, 09:11 »

Если у тебя в таблице данные не будут самопроизвольно меняться (к примеру какой нить параметр типа температуры и прочая),
то применяй при каждом добавлении строки resizeRowToContents(int номер строки). (заметь там будет ресайзиться 1 строка, а при вызове Rows будут все).
В одной из таблиц у меня данные как-раз и меняются в зависимости от выбранной строки другой таблицы. И получается что при переходе с одной строки на другую одной таблицы, в другой данные меняются и каждый раз вызывается resizeRowsToContents(). Тут видимо уже ничего не поделаешь ... или не использовать эту функцию, что приводит не к очень красивлму отображению или использовать и наблюдать небольшую задержку ((((
А вот по поводу resizeRowToContents(int номер строки), как же мне ее применить при добавлении строки ... если после добавления мне нужно сначало обновить таблицу, что приводит к сбросу ранее подогнанных под размер контента строк. Такчто и при добавлении приходится использовать resizeRowыToContents
Записан
Bepec
Гость
« Ответ #14 : Ноябрь 25, 2011, 10:32 »

Кхм. возможно ВЫ просто так думаете.

Меняются же не все 250+++ строк?

Если же  у вас, как я понимаю, вложенные таблицы(1 строке в верхней таблице соответвует целая таблица нижнего уровня).

Тогда решайте, что вам проще:
1) выяснить приемлимый и устраивающий всех размер ячеек и тупо задать его фиксированно(и не будет вызовов и тормозов).
2) применять функцию ресайза к тем строкам, которые видны. Там помоему даже функция есть выдающая видимые строки.
Т.е. вместо 250+ строк будет обновляться 10-40(я не вкурсе какая у ВАС таблица).
3) подумать что не так и как можно реализовать по другому Улыбающийся
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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