Grid с встроенными виджетами, оптимизация
От: Аноним  
Дата: 08.02.13 07:48
Оценка:
Есть таблица (GridWidget), скажем, 10000 строк на 100 столбцов. Каждая ячейка таблицы может содержать какой-то элемент — edit, button, checkbox и т.д. Создавать 1000000 различных элементов в каждой ячейке ИМХО неразумно и не нужно. Большая часть элементов просто не видна, из тех которые видны — только один элемент может быть активным (в фокусе ввода).
В аналогичной реализации на MFC я поступал так: были соответствующие классы InPlaceEdit, InPlaceButton и т.д., которые имели статические методы, умеющие отрисовывать соответствующие контролы без создания реального окна (hwnd). Эти методы вызывались гридом при отрисовке. А при щелчке (активизации ввода) на ячейке создавался (или подключался заранее созданный) элемент управления соответствующего типа.

Есть ли в qt какое-то готовое решение, аналогичное данному, или же придется все программировать вручную?
Re: Grid с встроенными виджетами, оптимизация
От: Аноним  
Дата: 08.02.13 07:54
Оценка:
поправка — элемент грида конечно же QTableWidget
Re: Grid с встроенными виджетами, оптимизация
От: Arsenicum Россия  
Дата: 08.02.13 09:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть таблица (GridWidget), скажем, 10000 строк на 100 столбцов. Каждая ячейка таблицы может содержать какой-то элемент — edit, button, checkbox и т.д. Создавать 1000000 различных элементов в каждой ячейке ИМХО неразумно и не нужно. Большая часть элементов просто не видна, из тех которые видны — только один элемент может быть активным (в фокусе ввода).

А>В аналогичной реализации на MFC я поступал так: были соответствующие классы InPlaceEdit, InPlaceButton и т.д., которые имели статические методы, умеющие отрисовывать соответствующие контролы без создания реального окна (hwnd). Эти методы вызывались гридом при отрисовке. А при щелчке (активизации ввода) на ячейке создавался (или подключался заранее созданный) элемент управления соответствующего типа.

А>Есть ли в qt какое-то готовое решение, аналогичное данному, или же придется все программировать вручную?


Есть аналог — делегаты и для их использования нужно перейти на QTableView и модели. Да и вообще QTableWidget это legacy и от него лучше отказаться.
Re: Grid с встроенными виджетами, оптимизация
От: Qt-Coder  
Дата: 08.02.13 11:40
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Есть ли в qt какое-то готовое решение, аналогичное данному, или же придется все программировать вручную?


Готового нет, нужно самому. На QTableView (наследника) вешается (setItemDelegate) делегат QStyledItemDelegate (наследник).
У делегата переопределяется свойство createEditor() В нем создается компонент для редактирования.
В QTableView ставится политика редактирования — setEditTriggers(). Можно задать что по одинарному / двойному щелчку создается компонент редактирования.
Re: Grid с встроенными виджетами, оптимизация
От: Qt-Coder  
Дата: 08.02.13 11:44
Оценка:
Здравствуйте, Аноним, Вы писали:

Еще хочу "порадовать" что таблица 100 000 на 100 очень плохо отрисовывается.
Qt умеет подгружать порциями по 128 элементов, но при этом элементы нельзя пересортировать на лету. Сортирует только то, что отрисовано.
Re[2]: Grid с встроенными виджетами, оптимизация
От: Аноним  
Дата: 08.02.13 12:02
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC>Еще хочу "порадовать" что таблица 100 000 на 100 очень плохо отрисовывается.

QC>Qt умеет подгружать порциями по 128 элементов, но при этом элементы нельзя пересортировать на лету. Сортирует только то, что отрисовано.

Ну одновременно никогда 128 не будет, на экран столько не влезет. В крайнем случае можно сделать "листалку" загружать порциями по N элементов, а не сплошную таблицу.

Но все-таки каким образом отрисовывать ячейки? Во всех примерах встроенные виджеты (обычно edit, spinedit, редактирование времени) активизируются по двойному щелчку мыши. До этого все ячейки содержат просто текст.
Мне нужно отрисовать в ячейках например кнопки, чекбоксы или треугольники комбобоксов, чтобы они были отрисованные уже когда таблица отображается.
И по одинарному щелчку сразу активизировать элемент и передавать ему этот одинарный щелчек, чтобы было как меньше лишних действий. Хороший пример с CheckBox'ом: вы видите столбец с этими чекбоксами, щелкаете — и сразу галочка в чекбоксе ставится или снимается.
Re[3]: Grid с встроенными виджетами, оптимизация
От: Qt-Coder  
Дата: 08.02.13 12:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но все-таки каким образом отрисовывать ячейки? Во всех примерах встроенные виджеты (обычно edit, spinedit, редактирование времени) активизируются по двойному щелчку мыши. До этого все ячейки содержат просто текст.

А>Мне нужно отрисовать в ячейках например кнопки, чекбоксы или треугольники комбобоксов, чтобы они были отрисованные уже когда таблица отображается.
А>И по одинарному щелчку сразу активизировать элемент и передавать ему этот одинарный щелчек, чтобы было как меньше лишних действий. Хороший пример с CheckBox'ом: вы видите столбец с этими чекбоксами, щелкаете — и сразу галочка в чекбоксе ставится или снимается.

Ну это немного посложнее, но возможно.
Можно назначить делегат колонке, вызвав setItemDelegateForColumn().
В самом делегате переопределить событие
void paint(QPainter * painter, const QStyleOptionViewItem & option,
const QModelIndex & index) const;
и
bool editorEvent(QEvent * event, QAbstractItemModel * model,
const QStyleOptionViewItem & option,
const QModelIndex & index)

В них можно нарисовать виджеты используя функции drawControl
Например, кнопка рисуется так
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOpt, painter);

В editorEvent() ловится событие
if (event->type() == QEvent::MouseButtonPress)
и взводится флаг нажатости.
Используя этот флаг paint() рисует либо нажатую либо отжатую кнопку. Также в editorEvent() можно бросить сигнал наружу о том что кнопку была нажата.
Re[4]: Grid с встроенными виджетами, оптимизация
От: Аноним  
Дата: 11.02.13 11:17
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC>Ну это немного посложнее, но возможно.

QC>Можно назначить делегат колонке, вызвав setItemDelegateForColumn().

Примерно понятно. А подскажите, в чем разница между setItemDelegate() и setItemDelegateForColumn()? В чем разница при их вызовах (я так понимаю, все равно делегат вызывается для каждой ячейки в отдельности)?
Re[5]: Grid с встроенными виджетами, оптимизация
От: Qt-Coder  
Дата: 12.02.13 03:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Примерно понятно. А подскажите, в чем разница между setItemDelegate() и setItemDelegateForColumn()? В чем разница при их вызовах (я так понимаю, все равно делегат вызывается для каждой ячейки в отдельности)?



Тем, что в случае setItemDelegateForColumn() можно не проверять номер колонки в делегате )))
Re[4]: Grid с встроенными виджетами, оптимизация
От: Аноним  
Дата: 18.02.13 11:44
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC>В editorEvent() ловится событие

QC>if (event->type() == QEvent::MouseButtonPress)
QC>и взводится флаг нажатости.
QC>Используя этот флаг paint() рисует либо нажатую либо отжатую кнопку. Также в editorEvent() можно бросить сигнал наружу о том что кнопку была нажата.

А как при нажатии и отпускании мыши отправить сигнал на перерисовку ячейки? Внутри делегата вроде нет никаких средств для этого и никакого доступа к самому qtableview (в котором вроде бы есть метод update(), который можно было бы применить для того чтобы инициировать перерисовку)
Re[5]: Grid с встроенными виджетами, оптимизация
От: Qt-Coder  
Дата: 18.02.13 12:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Qt-Coder, Вы писали:


А>А как при нажатии и отпускании мыши отправить сигнал на перерисовку ячейки? Внутри делегата вроде нет никаких средств для этого и никакого доступа к самому qtableview (в котором вроде бы есть метод update(), который можно было бы применить для того чтобы инициировать перерисовку)


метод paint() будет вызван автоматически.
Re[6]: Grid с встроенными виджетами, оптимизация
От: Аноним  
Дата: 18.02.13 12:21
Оценка:
Здравствуйте, Qt-Coder, Вы писали:

QC>метод paint() будет вызван автоматически.

после нажатия вызывается, а после отпускания — нет. А надо бы например нарисовать кнопочку "отжатой".
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.