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

Войти
 
   Начало   Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
Страниц: 1 2 3 [4] 5 6 ... 10
 31 
 : Сентября 10, 2025, 10:00 
Автор demaker - Последний ответ от demaker

Цитировать
У меня используется мьюченный std::unordered_map ну чтобы threadsafe был и данные добавляются при этом формируется ключ, чтобы
если уже такие данные есть до мы просто их обновляем.
не вижу особо проблем - в модели у тебя все равно будет вектор/дек так как ты в какой-то момент захочешь сортировку по колонкам делать и менять содержимое элементов
надо только аккуратно держать в синке вектор с мапой
в целом можно избежать вставки в середину лайфхаком - всегда добавлять новое в конец (beginInsertRows) а потом пересортировывать (вызывая в просессе layoutAboutToBeChanged/layoutChanged)
Делать фулл reset не очень удобно на практике так как полностью перерисоывает вьюпорт, сбрасывает селекшн.
Вьюша же рисует только то что попадает во вьпорт и если ряды добавляются вне его то никаких перерисовок не будет

Здесь как ты советуешь планирую сделать что-то типа
Код
C++ (Qt)
std::mutex m;
std::unordered_map<Key, std::shared_ptr<T>> map;
std::deque<shared_ptr<T>> q;
 

И получается если размер deque изменился то соответственно мы делаем beginInsertRows - endInsertRows а если нет обновляем данные.

Т.е ниже у меня был vector, теперь будет deque

Надеюсь правилно тебя понял)

 32 
 : Сентября 10, 2025, 09:58 
Автор demaker - Последний ответ от demaker
beginInsertRows должен предшествовать изменению данных, endInsertRows должен быть после
иначе может разъехаться стейт
для некоторых вьюх это может работать (если колбек на beginInsertRows пустой) для некоторых нет
тут только смотреть конкретную реализацию (и я конечно из головы уже не помню че там 14 лет назад было дело)

Ага понял

Код
C++ (Qt)
 
beginInsertRows( QModelIndex(), prvsz, cursz);
 
wgtvec.swap(v);
 
endInsertRows();
 

 33 
 : Сентября 10, 2025, 01:11 
Автор demaker - Последний ответ от Авварон
Собственно сама модель подписана на beginInsertRows и вызывает rowCount который тут ожидается старый

 34 
 : Сентября 10, 2025, 00:42 
Автор demaker - Последний ответ от Авварон
beginInsertRows должен предшествовать изменению данных, endInsertRows должен быть после
иначе может разъехаться стейт
для некоторых вьюх это может работать (если колбек на beginInsertRows пустой) для некоторых нет
тут только смотреть конкретную реализацию (и я конечно из головы уже не помню че там 14 лет назад было дело)

 35 
 : Сентября 09, 2025, 22:26 
Автор demaker - Последний ответ от demaker

Цитировать
У меня используется мьюченный std::unordered_map ну чтобы threadsafe был и данные добавляются при этом формируется ключ, чтобы
если уже такие данные есть до мы просто их обновляем.
не вижу особо проблем - в модели у тебя все равно будет вектор/дек так как ты в какой-то момент захочешь сортировку по колонкам делать и менять содержимое элементов
надо только аккуратно держать в синке вектор с мапой
в целом можно избежать вставки в середину лайфхаком - всегда добавлять новое в конец (beginInsertRows) а потом пересортировывать (вызывая в просессе layoutAboutToBeChanged/layoutChanged)
Делать фулл reset не очень удобно на практике так как полностью перерисоывает вьюпорт, сбрасывает селекшн.
Вьюша же рисует только то что попадает во вьпорт и если ряды добавляются вне его то никаких перерисовок не будет

Хотелось немного по этой части уточнить)

Правильно ли я понял принцип добавления\обновления элементов в моедль

Код
C++ (Qt)
 
class Widget : public QWidget
{
...
 
private:
 std::vector<std::pair<Key, Type>> wgtvec;
 Table *model;
}
 
Widget::Widget(...) : ...
{
 
  model = new TableModel(&wgtvec);
}
 
void Widget::updateModel()
{
     //запрашиваем вектор с данными
     std::vector<std::pair<Key, Type>> v = threadsafe_unordered_map.getVector();      
 
     int cursz = v.size();      
     int prvsz = wgtvec.size();
     int count = cursz- prvsz;
 
     if(count > 0){
            wgtvec.swap(v);        
            beginInsertRows( QModelIndex(), prvsz, cursz);
            endInsertRows();
        }
      }
      else if(count == 0){
 
        QRect viewportRect = tableView->viewport()->rect();
 
        QModelIndex topLeft = tableView->indexAt(viewportRect.topLeft());
        QModelIndex bottomRight = tableView->indexAt(viewportRect.bottomRight());
 
         if(topLeft.isValid() && bottomRight.isValid()){
 
              model->dataChanged(topLeft,bottomRight);
 
        }
 
      }
}
 





 36 
 : Сентября 09, 2025, 22:24 
Автор demaker - Последний ответ от demaker
Цитировать
Или кривовато???
я бы ожидал багов да=)
весь смысл QTableView в вертикальном хедере который позволяет менять высоту строк (а как следствие высоту всей вью и макс значение скроллбара)
Используй QTreeView с uniformRowHeights=true https://doc.qt.io/qt-6/qtreeview.html#uniformRowHeights-prop - так оно будет вычислять скроллбар как firstRowHeight*rowCount() а не суммировать в цикле.
Скорее всего тормоза у тебя не уйдут так потому что все равно чтобы посчитать высоту вьюпорта скроллбара надо просуммировать вертикальные хедеры
Большое спасибо! Помогло)

 37 
 : Сентября 05, 2025, 16:41 
Автор demaker - Последний ответ от Авварон
Цитировать
Или кривовато???
я бы ожидал багов да=)
весь смысл QTableView в вертикальном хедере который позволяет менять высоту строк (а как следствие высоту всей вью и макс значение скроллбара)
Используй QTreeView с uniformRowHeights=true https://doc.qt.io/qt-6/qtreeview.html#uniformRowHeights-prop - так оно будет вычислять скроллбар как firstRowHeight*rowCount() а не суммировать в цикле.
Скорее всего тормоза у тебя не уйдут так потому что все равно чтобы посчитать высоту вьюпорта скроллбара надо просуммировать вертикальные хедеры

Цитировать
У меня используется мьюченный std::unordered_map ну чтобы threadsafe был и данные добавляются при этом формируется ключ, чтобы
если уже такие данные есть до мы просто их обновляем.
не вижу особо проблем - в модели у тебя все равно будет вектор/дек так как ты в какой-то момент захочешь сортировку по колонкам делать и менять содержимое элементов
надо только аккуратно держать в синке вектор с мапой
в целом можно избежать вставки в середину лайфхаком - всегда добавлять новое в конец (beginInsertRows) а потом пересортировывать (вызывая в просессе layoutAboutToBeChanged/layoutChanged)
Делать фулл reset не очень удобно на практике так как полностью перерисоывает вьюпорт, сбрасывает селекшн.
Вьюша же рисует только то что попадает во вьпорт и если ряды добавляются вне его то никаких перерисовок не будет

 38 
 : Сентября 05, 2025, 15:35 
Автор demaker - Последний ответ от demaker
Авварон
Такой вопрос)

Можно ли допустим взять ту же вьюху(QTableView) и выводить в ней столько записей сколько помещается на отображение при этом использовать свой вертикальный скролл бар
Код
C++ (Qt)
class TableView : public QTableView
{
...
public:
   int numberRows;
}
 
 
bool TableView::viewportEvent(QEvent *event)
{
if(event->type == QEvent::Paint){
 
  int hrow = rowHeight(0);
 
  if(hrow > 0){
     numberRows = viewport()->size().height() / hrow
 }
 else{
   numberRows = 1;
 }
 
 return QTableView::viewportEvent(event);
 
}
 

Делаем нужную выборку из вектора

Код
C++ (Qt)
 
std::vector<std::pair<Key, Type>> Core::GetTableData(int pos, nrows)
{
   std::vector<std::pair<Key, Type>> v = threadsafe_unordered_map.get_vecctor();
   std::vector<std::pair<Key, Type>> res;
 
   for(int i = 0; i < nrows; ++i)
  {      
     std::pair<Key, Type> p = v[pos + i];
     res.push_back(p);
  }
 
   return res;
}
 



Код
C++ (Qt)
 
class MainWindow : public QMainWindow
{
 
private:
std::vector<std::pair<Key, Type>> v;
 
}
 
MainWindow::MainWindow(...)
{
  ...
  model = new TableModel(&v, this)
}
 
void MainWindow::UpDateTable()
{
   v =  core.GetTableData(ui->verticalScroll->sliderPosition(), ui->tableView->numberRows);
   model->upDate(); //beginResetModel() endResetModel()
}
 

Или кривовато???

У меня используется мьюченный std::unordered_map ну чтобы threadsafe был и данные добавляются при этом формируется ключ, чтобы
если уже такие данные есть до мы просто их обновляем.

Поэтому при формирование вектора могут добавиться как в середину так и в начало и как использовать insert в таком случае я не понимаю?
Нужно как-то предварительно рассчитывать куда insert делать.



 39 
 : Сентября 05, 2025, 14:29 
Автор Авварон - Последний ответ от Авварон
Ну мы платим ветку

 40 
 : Сентября 05, 2025, 13:45 
Автор demaker - Последний ответ от Авварон
А, ну и вместо reset советую insert/remove rows

Страниц: 1 2 3 [4] 5 6 ... 10

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