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

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

Страниц: 1 2 3 [4] 5   Вниз
  Печать  
Автор Тема: Трудоемкие задачи (прервать или продолжить). Как прервать?  (Прочитано 32475 раз)
daimon
Гость
« Ответ #45 : Декабрь 10, 2009, 21:28 »

Страшная функция - не оптимизирована страшно, краткая характеристика. Думаю как упрастить.
Что можна заменить на более быстродействующее?
Смысл работы: передаю список выделений итемов, составляю список выделенных колонок и строк; по этому списку формирую список итемов для сортировки, сортирую полученный список и устанавливаю эти итемы в выделенные колонки/строки. Списков много, как уменьшить. Преимущество такой сортировки ячеек для таблицы - могу сортировать разные колонки, находящиеся не рядом (поэтому и список выделений selectionRange) и могу выделять ячейки с помощью Ctrl , недостатки для колонки 10000 итемов сортирует долго
Кто чем может помогите? Грустный
10 тысяч итемов - для сортировки не объем, если Вы сортируете грамотно это должно выполняться за доли секунды. Для начала проверьте что все списки/контейнеры подаются по ссылке. Не поможет - выкладывайте Вашу "страшную ф-цию", будем смотреть.
Проблема даже не в сортировке, а в обновлении всех значений таблицы после сортировки somethingChanged(), если таблица 10000*10000 обновляется минуты 2 (обновляю потому, что после сортировки некоторые ячейки изменились - нужно изменить зависящие от этих ячеек другие ячейки). Сама функция
Код
C++ (Qt)
#define UPDATE_STEP 100
 
bool UpdateProgress( QProgressDialog & progress, int row )
{
int k=1% 100;
if ((row+1 ) % UPDATE_STEP) return false; // update once per UPDATE_STEP
progress.setValue(row); // calls processEvents for modal dialog
return progress.wasCanceled();
}
 
bool Spreadsheet::sort_data(const QList<QTableWidgetSelectionRange>& range, const SpreadsheetCompare &compare)
{
 
if(range.isEmpty())
{return false;}
else
{
QProgressDialog progress(this);
progress.setModal(true);
progress.setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint|Qt::WindowTitleHint);
 
progress.setMinimumDuration(1);
progress.setLabelText(tr("Checking range 1/5"));
progress.setMaximum(range.size());
for(int it=0;it<range.size();it++)
{
if(range[it].leftColumn()<0||range[it].bottomRow()<0||range[it].rightColumn()<0||range[it].topRow()<0)
{return false;}
qApp->processEvents();
if (UpdateProgress(progress, it)) return false;
}
progress.setLabelText(tr("Adding rows & columns 2/5"));
progress.setMaximum(range.size());
progress.setValue(0);
 
 
 
 
QList<int> columns;
QList<int> rows;
for(int i=0;i<range.size();i++)
{
for(int col=range[i].leftColumn();col<=range[i].rightColumn();col++)
 
{if(columns.indexOf(col) ==-1) columns.push_back(col);qApp->processEvents();}
for(int row=range[i].topRow();row<=range[i].bottomRow();row++)
{if(rows.indexOf(row) ==-1) rows.push_back(row);qApp->processEvents();}
if (UpdateProgress(progress, i)) return false;
}
progress.setLabelText(tr("Sorting 3/5"));
progress.setMaximum(2);
progress.setValue(0);
qSort(columns.begin(),columns.end());
 
qSort(rows.begin(),rows.end());
 
QList<QList<QTableWidgetItem*>> data_for_sort;
progress.setLabelText(tr("Adding rows & columns 4/5"));
progress.setMaximum(rows.size());
progress.setValue(0);
 
 
for(int i=0;i<rows.size();i++)
 
{
if (UpdateProgress(progress, i)) return false;
QList<QTableWidgetItem*> row;
 
for(int j=0;j<columns.size();j++)
{
 
if(is_item_in_list_selection_range(range, rows[i],  columns[j])==true )
{
if(isError_in_cell(rows[i],columns[j])==true)
{return false;}
else if(item(rows[i],columns[j]))
{
 
row.push_back(takeItem(rows[i],columns[j]));
}
qApp->processEvents();
}
}
if(row.size()==columns.size()&&row.size()>0)
data_for_sort.push_back(row);
 
else
{
rows.removeOne(rows[i]);
i--;
}
row.clear();
}
 
 
QList<QList<QTableWidgetItem*>> temp=data_for_sort;
qStableSort(data_for_sort.begin(), data_for_sort.end(),compare);
 
if(data_for_sort==temp) {return false;}
 
set_calculate_function(true);
progress.setLabelText(tr("Setting Items 5/5"));
progress.setMaximum(rows.size());
progress.setValue(0);
for(int i=0;i<data_for_sort.size();i++)
 
{
 
 
for(int j=0;j<data_for_sort[i].size();j++)
{
if (UpdateProgress(progress, i)) return false;
//setFormula(rows[i], columns[j], data_for_sort[i][j]->data(Qt::EditRole).toString());
setItem(rows[i],columns[j],data_for_sort[i][j]);
qApp->processEvents();
 
 
}
 
// progress.setValue(((i)*10)/rows.size()+85);
}
 
set_calculate_function(false);
 
 
 
//progress.setValue(95);
 //  clearSelection();
 
progress.setValue(100);
if(! somethingChanged(progress,true)) return false;
//progress.setValue(100);
progress.cancel();
return true;
}
 
}
 
 
bool Spreadsheet::somethingChanged(QProgressDialog &progress,bool update)
{
if (autoRecalc&&!bool_calculate_function||update)
if(!recalculate(progress)) return false;
  if(!bool_calculate_function||update)
emit modified();
return true;
 
}
 
 
bool Spreadsheet::recalculate(QProgressDialog &progress) //мое работает
{
 
progress.setRange(0,RowCount);
for (int row = 0; row < RowCount; ++row) {
 
for (int column = 0; column < ColumnCount; ++column)
{
if (UpdateProgress(progress, row)) return false;
if( item(row, column))
if(item(row,column)->text()!="")
cell(row, column)->setDirty();
qApp->processEvents();
 
}
}
  viewport()-> update();
  return true;
 
}
 
class SpreadsheetCompare
{
public:
   bool operator()(const QList<QTableWidgetItem*> &row1,
                   const QList<QTableWidgetItem*> &row2) const
{
 
        int column = keys;
       if (column != -1) {
           if (row1[column] != row2[column])
{
parser p;
 
 
               if (ascending)
return row1[column]->text().toDouble()< row2[column]->text().toDouble();//*///p.calculation(row1[column].toStdString().c_str()) < p.calculation(row2[column].toStdString().c_str());
                else
                   return row1[column]->text().toDouble()> row2[column]->text().toDouble();//*///p.calculation(row1[column].toStdString().c_str()) > p.calculation(row2[column].toStdString().c_str());
 
           }
 
   }
   return false;
}
 
 
 
   int keys;
   bool ascending;
};
compare - ключ для сортировки
« Последнее редактирование: Декабрь 10, 2009, 21:37 от daimon » Записан
daimon
Гость
« Ответ #46 : Декабрь 12, 2009, 00:02 »

Кто может помогите?
« Последнее редактирование: Декабрь 12, 2009, 03:12 от daimon » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #47 : Декабрь 12, 2009, 01:20 »

Кто может помогите?
Я не "придираюсь" но с таким текстом как у Вас желание помочь быстро пропадает. Отрихтуйте, почистите

Код:
if (UpdateProgress(progress, i)) return false;	
Неудачное название если ф-ция возвращает false

- processEvents ест время ничего не делает (поскольку UpdateProgess это решает)

 "== true" выглядит не очень естественно
 
- текст должен выглядеть ровно (а не как бык поссал)
 
- возможно что тормоза в is_item_in_list_selection_range, покажите ее тоже

Вот когда все подправите - тогда и поговорим.
Записан
daimon
Гость
« Ответ #48 : Декабрь 12, 2009, 02:36 »

Кто может помогите?
Я не "придираюсь" но с таким текстом как у Вас желание помочь быстро пропадает. Отрихтуйте, почистите

-  
Код:
if (UpdateProgress(progress, i)) return false;	
Неудачное название если ф-ция возвращает false

- processEvents ест время ничего не делает (поскольку UpdateProgess это решает)

 "== true" выглядит не очень естественно
 
- текст должен выглядеть ровно (а не как бык поссал)
 
- возможно что тормоза в is_item_in_list_selection_range, покажите ее тоже

Вот когда все подправите - тогда и поговорим.
- processEvents ест время ничего не делает (поскольку UpdateProgess это решает) объясните строку не понятно
« Последнее редактирование: Декабрь 12, 2009, 02:40 от daimon » Записан
daimon
Гость
« Ответ #49 : Декабрь 12, 2009, 03:11 »

Вроде функцию подогнал под читабельность. Кто может как улучшить код? Грустный

Код
C++ (Qt)
bool Spreadsheet::is_item_in_list_selection_range(const QList<QTableWidgetSelectionRange>& range, int row_, int column)
{
if(range.isEmpty())
return false;
else
{
for(int it=0;it<range.size();it++)
{
if(range[it].leftColumn()<0||range[it].bottomRow()<0||range[it].rightColumn()<0||range[it].topRow()<0) return false;
qApp->processEvents();
}
for(int i=0;i<range.size();i++)
{
for(int col=range[i].leftColumn();col<=range[i].rightColumn();col++)
{
for(int row=range[i].topRow();row<=range[i].bottomRow();row++)
{
if(col==column&&row==row_) return true;
qApp->processEvents();
}
}
}
return false;
}
}
bool Spreadsheet::sort_data_with_GUI(const QList<QTableWidgetSelectionRange>& range)
{
if(range.isEmpty()) return false;
else
{
for(int it=0;it<range.size();it++)
{
if(range[it].leftColumn()<0||range[it].bottomRow()<0||range[it].rightColumn()<0||range[it].topRow()<0) return false;
qApp->processEvents();
}
QString error="";
 
for(int it=0;it<range.size();it++)
for(int i=0;i<range[it].rowCount();i++)
for(int j=0;j<range[it].columnCount();j++)
{
if(!item(range[it].topRow()+i ,range[it].leftColumn()+j)||item(range[it].topRow()+i ,range[it].leftColumn()+j)->text()=="")
{
error+=tr("item: ")+get_header_label(range[it].leftColumn()+j)+QString::number(range[it].topRow()+i+1)+tr(" - not value\n");}
}
if(error!="")
{
QMessageBox  *errorMessageDialog = new QMessageBox(this);
errorMessageDialog->setWindowTitle(tr(""));
errorMessageDialog->setText(tr("Invalid item(s) ( ? select Item with valid value)."));
errorMessageDialog->setIcon(QMessageBox::Critical);
  errorMessageDialog->setDetailedText(error);
errorMessageDialog->show();
return false;
}
else
{
Dialog_properties_datasheet_sort dialog;
QStringList interval_names_for_columns;
for(int it=0;it<range.size();it++)
for(int i=range[it].leftColumn();i<=range[it].rightColumn();i++)
{
if(interval_names_for_columns.indexOf(list_names_for_columns ()[i])==-1)interval_names_for_columns+=list_names_for_columns ()[i];
qApp->processEvents();
}
    dialog.setColumnRange(interval_names_for_columns);
if (dialog.exec())
{
if( !sort_data(range,dialog.get_settings_for_compare_from_dialog()))
{
QMessageBox::information(this,tr("Graphbuilder"),tr("Sort nothing has changed or cancel"));
return false;
}
}
return true;
}
}
}
#define UPDATE_STEP 100
 
bool UpdateProgress( QProgressDialog & progress, int row )
{
int k=1% 100;
if ((row+1 ) % UPDATE_STEP) return true; // update once per UPDATE_STEP
progress.setValue(row); // calls processEvents for modal dialog
return !progress.wasCanceled();
}
 
bool Spreadsheet::sort_data(const QList<QTableWidgetSelectionRange>& range, const SpreadsheetCompare &compare)
{
if(range.isEmpty())
return false;
else
{
QProgressDialog progress(this);
progress.setModal(true);
progress.setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint|Qt::WindowTitleHint);
progress.setMinimumDuration(1);
progress.setLabelText(tr("Checking range 1/5"));
progress.setMaximum(range.size());
for(int it=0;it<range.size();it++)
{
if(range[it].leftColumn()<0||range[it].bottomRow()<0||range[it].rightColumn()<0||range[it].topRow()<0) return false;
//qApp->processEvents();
if (!UpdateProgress(progress, it)) return false;
}
progress.setLabelText(tr("Adding rows & columns 2/5"));
progress.setMaximum(range.size());
progress.setValue(0);
QList<int> columns;
QList<int> rows;
for(int i=0;i<range.size();i++)
{
for(int col=range[i].leftColumn();col<=range[i].rightColumn();col++)
{if(columns.indexOf(col) ==-1) columns.push_back(col);qApp->processEvents();}
for(int row=range[i].topRow();row<=range[i].bottomRow();row++)
{if(rows.indexOf(row) ==-1) rows.push_back(row);qApp->processEvents();}
if (!UpdateProgress(progress, i)) return false;
}
progress.setLabelText(tr("Sorting 3/5"));
progress.setMaximum(2);
progress.setValue(0);
qSort(columns.begin(),columns.end());
qSort(rows.begin(),rows.end());
QList<QList<QTableWidgetItem*>> data_for_sort;
progress.setLabelText(tr("Adding data to sort 4/5"));
progress.setMaximum(rows.size());
progress.setValue(0);
 
for(int i=0;i<rows.size();i++)
{
if (!UpdateProgress(progress, i)) return false;
QList<QTableWidgetItem*> row;
 
for(int j=0;j<columns.size();j++)
{
if(is_item_in_list_selection_range(range, rows[i],  columns[j])==true )
{
if(isError_in_cell(rows[i],columns[j])==true)
return false;
else if(item(rows[i],columns[j]))
row.push_back(takeItem(rows[i],columns[j]));
 
// qApp->processEvents();
}
}
if(row.size()==columns.size()&&row.size()>0)
data_for_sort.push_back(row);
else
{
rows.removeOne(rows[i]);
i--;
}
row.clear();
}
 
QList<QList<QTableWidgetItem*>> temp=data_for_sort;
qStableSort(data_for_sort.begin(), data_for_sort.end(),compare);
 
if(data_for_sort==temp) return false;
 
set_calculate_function(true);
progress.setLabelText(tr("Setting Items 5/5"));
progress.setMaximum(rows.size());
progress.setValue(0);
for(int i=0;i<data_for_sort.size();i++)
{
for(int j=0;j<data_for_sort[i].size();j++)
{
if (!UpdateProgress(progress, i)) return false;
//setFormula(rows[i], columns[j], data_for_sort[i][j]->data(Qt::EditRole).toString());
setItem(rows[i],columns[j],data_for_sort[i][j]);
//qApp->processEvents();
}
}
 
set_calculate_function(false);/////разрешает обновлять ячейки таблицы (true - запрещает).
progress.setValue(100);
if(! somethingChanged(progress,true)) return false;
//progress.setValue(100);
return true;
}
}
 
bool Spreadsheet::somethingChanged(QProgressDialog &progress,bool update)
{
if (autoRecalc&&!bool_calculate_function||update)
if(!recalculate(progress)) return false;
if(!bool_calculate_function||update)
emit modified();
return true;
}
 
bool Spreadsheet::recalculate(QProgressDialog &progress) //мое работает
{
progress.setRange(0,RowCount);
for (int row = 0; row < RowCount; ++row)
{
for (int column = 0; column < ColumnCount; ++column)
{
if (!UpdateProgress(progress, row)) return false;
if( item(row, column))
if(item(row,column)->text()!="")
cell(row, column)->setDirty();
qApp->processEvents();
}
}
  viewport()-> update();
  return true;
}
 
class SpreadsheetCompare
{
public:
int keys;
   bool ascending;
   bool operator()(const QList<QTableWidgetItem*> &row1, const QList<QTableWidgetItem*> &row2) const
{
int column = keys;
       if (column != -1)
{
           if (row1[column] != row2[column])
{
       if (ascending)
return row1[column]->text().toDouble()< row2[column]->text().toDouble();
                else
                   return row1[column]->text().toDouble()> row2[column]->text().toDouble();
           }
}
return false;
}
};
« Последнее редактирование: Декабрь 12, 2009, 12:11 от daimon » Записан
daimon
Гость
« Ответ #50 : Декабрь 12, 2009, 12:10 »

Медленней всего работают операции серии "Adding data to sort 4/5". Как можно улучшить?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #51 : Декабрь 12, 2009, 14:23 »

Вроде функцию подогнал под читабельность. Кто может как улучшить код? Грустный
1) Уберите ВСЕ вызовы processEvents - везде. Посмотрите и подумайте зачем нужен UPDATE_STEP

2) Не создавайте избыточного кода методом copy/paste. Попробуйте так
Код
C++ (Qt)
bool Spreadsheet::is_item_in_list_selection_range(const QList<QTableWidgetSelectionRange>& range, int row_, int column)
{
for(int i = 0 ; i < range.size(); i++) {
if (row_ < range[i].topRow()) continue;
if (row_ > range[i].bottomRow()) continue;
if (column < range[i].leftColumn()) continue;
if (column > range[i].rightColumn()) continue;
return true;
}
return false;
}
Записан
daimon
Гость
« Ответ #52 : Декабрь 12, 2009, 19:23 »

Вроде функцию подогнал под читабельность. Кто может как улучшить код? Грустный
1) Уберите ВСЕ вызовы processEvents - везде. Посмотрите и подумайте зачем нужен UPDATE_STEP

2) Не создавайте избыточного кода методом copy/paste. Попробуйте так
Код
C++ (Qt)
bool Spreadsheet::is_item_in_list_selection_range(const QList<QTableWidgetSelectionRange>& range, int row_, int column)
{
for(int i = 0 ; i < range.size(); i++) {
if (row_ < range[i].topRow()) continue;
if (row_ > range[i].bottomRow()) continue;
if (column < range[i].leftColumn()) continue;
if (column > range[i].rightColumn()) continue;
return true;
}
return false;
}

Очень умное решение Шокированный
Записан
daimon
Гость
« Ответ #53 : Декабрь 12, 2009, 19:33 »

Код
C++ (Qt)
void Spreadsheet::setRowCount(int count_,QProgressDialog &dialog) //мое работает
{
dialog.setLabelText(tr("set Row"));
dialog.setRange(0,0);
dialog.setValue(0);
dialog.setMinimumDuration(1);
QTableWidget::setRowCount(count_);
RowCount=count_;
 
}
При установке большого числа строк возникает зависание приложения на 3 сек. Как в эти 3 сек выводить QProgressDialog со свойствами: setRange(0,0), setValue(0)? Заранее спасибо
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #54 : Декабрь 12, 2009, 19:57 »

Код
C++ (Qt)
void Spreadsheet::setRowCount(int count_,QProgressDialog &dialog) //мое работает
{
dialog.setLabelText(tr("set Row"));
dialog.setRange(0,0);
dialog.setValue(0);
dialog.setMinimumDuration(1);
QTableWidget::setRowCount(count_);
RowCount=count_;
 
}
При установке большого числа строк возникает зависание приложения на 3 сек. Как в эти 3 сек выводить QProgressDialog со свойствами: setRange(0,0), setValue(0)? Заранее спасибо
Число шагов известно, значит надо использовать setRange(0, count_).
Метод setRowCount позовет метод модели insertRows, вот там и обновляйте QProgressDialog
Записан
daimon
Гость
« Ответ #55 : Декабрь 12, 2009, 20:26 »

Код
C++ (Qt)
void Spreadsheet::setRowCount(int count_,QProgressDialog &dialog) //мое работает
{
dialog.setLabelText(tr("set Row"));
dialog.setRange(0,0);
dialog.setValue(0);
dialog.setMinimumDuration(1);
QTableWidget::setRowCount(count_);
RowCount=count_;
 
}
При установке большого числа строк возникает зависание приложения на 3 сек. Как в эти 3 сек выводить QProgressDialog со свойствами: setRange(0,0), setValue(0)? Заранее спасибо
Число шагов известно, значит надо использовать setRange(0, count_).
Метод setRowCount позовет метод модели insertRows, вот там и обновляйте QProgressDialog
Пока я использую класс QTableWidget и метода insertRows я не видел
Записан
daimon
Гость
« Ответ #56 : Декабрь 12, 2009, 21:42 »

Можете подкинуть пример редактируемой модели таблицы с несколькими ролями для данных QAbstractTableModel(интересует контейнер для данных - какой его вид)
Записан
daimon
Гость
« Ответ #57 : Декабрь 13, 2009, 17:27 »

Как быть с зависанием интерфейса для setRowCount(50000) в QTableWidget? Можна ли сделать, чтоб на время выполнения задачи отображался прогрессдиалог с бегающим уровнем (range-0,0 value - 0)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #58 : Декабрь 13, 2009, 17:43 »

Пока я использую класс QTableWidget и метода insertRows я не видел
Значит плохо смотрели. У любой таблицы есть модель у которой есть метод insertRows.
Записан
daimon
Гость
« Ответ #59 : Декабрь 13, 2009, 18:04 »

Пока я использую класс QTableWidget и метода insertRows я не видел
Значит плохо смотрели. У любой таблицы есть модель у которой есть метод insertRows.
Как тогда вызвать эту функцию?
Записан
Страниц: 1 2 3 [4] 5   Вверх
  Печать  
 
Перейти в:  


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