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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSplitter, QListView и их ресайз.  (Прочитано 4965 раз)
Visario
Гость
« : Июль 23, 2008, 15:16 »

Есть QSplitter и он контролирует кастомного QListView.
При этом gridSize подстраивается под высоту этого view в resizeEvent(), и если сделать view->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded), то иногда возникает бесконечный цикл:
0. убирается скроллбар, так как все элементы влезают
1. gridSize увеличивается, т.к. места стало больше
2. контент перестает влезать и пояляется скроллбар
3. gridSize уменьшается и возвращаемся к пункту 0.

Пробовал делать setSizes() сплиттеру, когда размер оказывался в "опасной зоне", но это выглядело ужасно, так как сплиттер все еще в движении и курсор мыши все еще над "опасной зоной".
Перегрузка moveSplitter и closestLegalPosition тоже не помогла, так как они не виртуальны =(

Как лучше разрулить эти ситуацию?
« Последнее редактирование: Июль 24, 2008, 09:08 от Visario » Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #1 : Июль 23, 2008, 22:21 »

Былобы неплохо увидеть код, и воспроизвесть все это у себя
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
ритт
Гость
« Ответ #2 : Июль 23, 2008, 23:15 »

а имеет ли смысл менять gridSize сразу по изменении размеров? может сделать это отложенным методом (по таймеру, например) ? - и циклить тогда не будет
Записан
Visario
Гость
« Ответ #3 : Июль 24, 2008, 08:13 »

Былобы неплохо увидеть код, и воспроизвесть все это у себя


Код:
#include <QtCore>
#include <QtGui>

class ItemDelegate: public QAbstractItemDelegate {
public:
ItemDelegate(QListView *view): QAbstractItemDelegate(view) {
mView = view;
}

protected:
virtual QSize sizeHint( const QStyleOptionViewItem &, const QModelIndex &) const {
return mView->gridSize();
}

virtual void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const {
QRect rect = option.rect;
painter->setPen(Qt::white);
int v = (index.column() + 1) * (index.row() + 1) * 1.5;
painter->setBrush(QColor(qMin(255, v*v/2), qMin(255, v*v), qMin(255, v*2)));
painter->drawRect(rect);
}

private:
QListView *mView;
};

class ListView : public QListView {
public:
ListView(QWidget *parent = 0)
: QListView(parent) {
setViewMode(QListView::IconMode);
setResizeMode(QListView::Adjust);
setUniformItemSizes(true);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
setWrapping(false);
setItemDelegate(mDelegate = new ItemDelegate(this));
}

~ListView() {
delete mDelegate;
}

protected:
virtual void resizeEvent(QResizeEvent * event) {
QListView::resizeEvent(event);

int sbExt = horizontalScrollBar()->isVisible() ? horizontalScrollBar()->sizeHint().height() : 0;
int gridSize = height() - sbExt;
setGridSize(QSize(gridSize, gridSize));
qDebug() << "resizeEvent" << gridSize;
}

private:
ItemDelegate *mDelegate;
};


int main(int argc, char *argv[]) {
QApplication app(argc, argv);

QStringListModel *model = new QStringListModel();
QStringList list = QString("abcdefg1234567").split("");
model->setStringList(list);

ListView *view = new ListView();
view->setModel(model);
view->resize(800, 80);
view->show();
return app.exec();
 }

После запуска, нужно немного уменьшить высоту, чтобы все элементы влезли.
Записан
Visario
Гость
« Ответ #4 : Июль 24, 2008, 08:28 »

а имеет ли смысл менять gridSize сразу по изменении размеров? может сделать это отложенным методом (по таймеру, например) ? - и циклить тогда не будет

Смысл менять gridSize сразу есть.
Не пробовал с таймером, но думаю, что это не поможет, т.к. размер будет скакать по таймеру.

Тут нужно как-то избежать определенных размеров (optSize = width() / rowCount() < height() < optSize + sbExt). В примере сверху можно было бы просто вызвать resize() с безопасным размером, но со сплиттером это не поможет.

Пофиксенная версия main функции:
Код:
int main(int argc, char *argv[]) {
QApplication app(argc, argv);

QStringListModel *model = new QStringListModel();
QStringList list = QString("abc1234567").split("");
model->setStringList(list);

ListView *view = new ListView();
view->setModel(model);

QSplitter splitter(Qt::Vertical);
splitter.addWidget(new QWidget());
splitter.addWidget(view);
splitter.resize(800, 140);
splitter.show();
return app.exec();
 }
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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