Просмотр сообщений
|
Страниц: [1] 2 3 ... 66
|
2
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 13, 2025, 20:34
|
Это связано с тем что tablemodel привязана к treview? Или в коде проблема?
в коде, все вью умеют в разные селекшоны проверь что флаги позволяют выделать несколько строк вообще Делаю так C++ (Qt) Qt::ItemFlags MyTableModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::NoItemFlags; return QAbstractTableModel::flags(index) | Qt::ItemIsSelectable; }
Причем если поменять QAbstractTableModel на QAbstractItemModel будет падать приложение
|
|
|
3
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 13, 2025, 00:58
|
Не получается выделить несколько строк. Делаю так: C++ (Qt) void TreeView::mousePressEvent(QMouseEvent *e) { if(e->modifiers() & Qt::Controlmodifier) { QModelIndex idx = indexAt(e->pos()); QModelIndex topLeft = model()->index(idx.row(), 0, QModelIndex()); QModelIndex bottomRight = model()->index(idx.row(), model()->columnCount() - 1, QModelIndex()); QItemSelection selection(topLeft, bottomRight); selectionModel()->select(selection, QItemSelectionModel::Select); } return QTreeView::mousePressEvent(e); }
Это связано с тем что tablemodel привязана к treview? Или в коде проблема?
|
|
|
4
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 13, 2025, 00:52
|
Ты ещё пишешь про unordered_map->vector. Если там простой std::copy, то полагаю, что строки в векторе могут перетасовываться = достаточно сложно вычислить какие индексы в модели обновились
Делаю вот так C++ (Qt) void container::add_mapping(Key key, Type &value) { std::lock_guard<std::mutex> l(mutex); auto it = unordered_map.find(key); if(it == unordered_map.end()){ Type *data = new Type; unordered_map.insert(std::make_pair(key, data)); vectror.push_back(data); } else{ *(it.operator->()->second) = value; } } std::vector<Type> container::get_vector() { std::lock_guard<std::mutex> l(mutex); std::vector<Type> v; for(auto e : vector){ v.push_back(*e); } return v; }
|
|
|
5
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 12, 2025, 13:25
|
Вообще SortFilterProxyModel может быть источником тормозов в том числе Она хорошая для простых кейзов, для сложных лучше писать сортировку руками Почему может не работать - хз надо читать код а мне лень может где-то контракт модели нарушен но в приведенном коде вроде всё ок
Сортировка работает, но фильтрация увы ((... Сделаю фильтрацию во время формирования вектора данных модели) Ну при этом у меня потеряется селектор блин, т.к индексы эементов будут другие И как тогда?..
|
|
|
6
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 12, 2025, 13:20
|
void Model::update(std::vector<Type> &fresh) { int prvsz = store.size(); int cursz = fresh.size(); beginInsertRows(QModelIndex(), prvsz, cursz); store.swap(fresh); endInsertRows(); } это кстати будет работать только если в новом векторе рядов больше чем в старом Да, согласен) Сделал вот так C++ (Qt) void Model::upDate(std::vector<typedata> &fresh, QTreeview *view) { int prvsz = v.size(); int cursz = fresh.size(); int count = cursz - prvsz; if (count>0) { beginInsertRows(QModelIndex(), prvsz, cursz - 1); v.swap(fresh); endInsertRows(); } else if(count==0){ QRect viewportRect = view->viewport()->rect(); QModelIndex topLeft = view->indexAt(viewportRect.topLeft()); QModelIndex bottomRight = view->indexAt(viewportRect.bottomRight()); if(topLeft.isValid() && bottomRight.isValid()){ dataChanged(topLeft,bottomRight); } } else { beginInsertRows(QModelIndex(), cursz , prvsz - 1); v.swap(fresh); endInsertRows(); } }
|
|
|
7
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 10, 2025, 16:28
|
Блин после того как сделал почему-то фильтрация отвалилась C++ (Qt) class Model : public ... { private: std::vector<Type> store; } void Model::update(std::vector<Type> &fresh) { int prvsz = store.size(); int cursz = fresh.size(); beginInsertRows(QModelIndex(), prvsz, cursz); store.swap(fresh); endInsertRows(); }
C++ (Qt) Widget::Widget(...) : ... { model = new TableModel(..., this); sort = new SortFilterProxyModel(this); sort->setSourceModel(model); treeview = new TreeView(this); treeview->setModel(sort); }
C++ (Qt) void Widget::updateModel() { int cursz = v.size(); int prvsz = wgtvec.size(); int count = cursz- prvsz; if(count > 0){ std::vector<Type> v = threadsafe_unordered_map.getVector(); model->update(v); } 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); } } }
Пробовал делать Но увы не помогает((
|
|
|
8
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 10, 2025, 10:00
|
У меня используется мьюченный 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 Надеюсь правилно тебя понял)
|
|
|
9
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 10, 2025, 09:58
|
beginInsertRows должен предшествовать изменению данных, endInsertRows должен быть после иначе может разъехаться стейт для некоторых вьюх это может работать (если колбек на beginInsertRows пустой) для некоторых нет тут только смотреть конкретную реализацию (и я конечно из головы уже не помню че там 14 лет назад было дело)
Ага понял C++ (Qt) beginInsertRows( QModelIndex(), prvsz, cursz); wgtvec.swap(v); endInsertRows();
|
|
|
10
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 09, 2025, 22:26
|
У меня используется мьюченный 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); } } }
|
|
|
11
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 09, 2025, 22:24
|
Или кривовато??? я бы ожидал багов да=) весь смысл QTableView в вертикальном хедере который позволяет менять высоту строк (а как следствие высоту всей вью и макс значение скроллбара) Используй QTreeView с uniformRowHeights=true https://doc.qt.io/qt-6/qtreeview.html#uniformRowHeights-prop - так оно будет вычислять скроллбар как firstRowHeight*rowCount() а не суммировать в цикле. Скорее всего тормоза у тебя не уйдут так потому что все равно чтобы посчитать высоту вьюпорта скроллбара надо просуммировать вертикальные хедеры Большое спасибо! Помогло)
|
|
|
12
|
Qt / Model-View (MV) / Re: ModelView большое количество данных
|
: Сентября 05, 2025, 15:35
|
Авварон Такой вопрос) Можно ли допустим взять ту же вьюху(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 делать.
|
|
|
13
|
Qt / Model-View (MV) / ModelView большое количество данных
|
: Сентября 05, 2025, 11:57
|
Всем доброго времени суток! Возникла проблема с отображением большого количества строк в QAbstractTableModel. Прорисовка графики начинает подвисать, когда количество строк в таблице в районе 1500. Данные берутся из std::unordered_map и затем заполняется std::vector<std::pair<KEY, TYPE>> v и закидывается в модель. В модели переопределил методы data, flags, rows, columns. Есть метод upDate(), так как когда вычитываем свежую порцию данных ,то хотим их обновить в модели(например по таймеру 500ms) C++ (Qt) TableModel::TableModel(std::vector<std::pair<uint32_t, uint32_t>> *v_ , QObject *parent) : QAbstractTableModel(parent) { v = v_; } void TableModel::upDate() { beginResetModel(); endResetModel(); } QVariant TableModel::data(const QModelIndex &index, int role) const { if(!index.isValid() || v->size() == 0){ return QVariant(); }else{ switch(role){ case Qt::DisplayRole: { switch(index.column()){ case 0 :{ return v->at(index.row()).first; } case 1:{ return v->at(index.row()).second; } default: return QVariant(); } } case Qt::TextAlignmentRole:{ return Qt::AlignCenter; } case Qt::FontRole: { QFont f; f.setFamily("monospace"); f.setStyleHint(QFont::Monospace); return f; } default: return QVariant(); } } }
Хотелось бы узнать насколько корректны мои действия в плане обновления данных модели? Нужно ли именно все данные подгружать в модель? Хочется подгружать именно ту область данных, которая на данный момент отображается на view)) Может есть другие механизмы более правильные? Может мне стоит использовать canFetchMore, fetchMore? Не получится ли при этом что добавлю в модель все 1500 строк и опять также графика вновь будет подвисать? Спасибо!
|
|
|
14
|
Qt / Общие вопросы / Re: Проблема с подключением DLL на VS и QtCreator
|
: Октября 25, 2024, 09:48
|
правда это на другой машине и там нету VS ну если там используется не тот же компилятор (msvc toolset), которым ты собрал библиотеку, то чему ты удивляешься. Видимо, мы должны сами угадать какой у тебя компилятор используется на другой машине. Извините что сразу не уточнил  Да в студии используется стандартный компилятор(msvc toolset), а в Qt MinGW32bit Т.е получается, что библа используемая в проекте должна быть собрана тем же компилятором что и сам проект иначе никак. Я правильно понимаю? Может можно как-то настроить?
|
|
|
15
|
Qt / Общие вопросы / Проблема с подключением DLL на VS и QtCreator
|
: Октября 24, 2024, 22:31
|
Доброго времени суток! Имеется библиотека созданная в VS2022 Типа: example.h #pragma once
#ifdef EXAMPLE_EXPORTS #define EXAMPLE_API __declspec(dllexport) #else #define EXAMPLE_API __declspec(dllimport) #endif
EXAMPLE_API void Get_Example();
example.cpp #include "pch.h" #include "example.h" #include <iostream>
void Get_Example() { std::cout << "hello example\n"; }
Если я подключаю данную библиотеку к проекту на VS то все хорошо и работает. Если же к проекту на Qt (правда это на другой машине и там нету VS) то не работает выдается ошибка undefined reference to -Z..Get_Example..
В pro-файле указываю путь к .h и .lib - файлам INCLUDEPATH += "C:\path" LIBS += "C:\path\name.lib"
Но если в хедере библиотеки сделать ...
extern "C"{ EXAMPLE_API void Get_Example(); }
пересобрать и подключить к Qt проекту то все норм. Пытался сделать в .pro файле Qt проекта добавить дефайн DEFINES += EXAMPLE_EXPORTS
Но безуспешно( Кто-нибудь сталкивался с такой проблемой? Подскажите в чем может быть причина?
|
|
|
|
|