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

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

Страниц: 1 2 [3] 4   Вниз
  Печать  
Автор Тема: Иерархические заголовки таблиц QTableWidget/QTableView...  (Прочитано 48297 раз)
ритт
Гость
« Ответ #30 : Апрель 09, 2008, 11:13 »

страх какой!

Змеище, делись кодом Улыбающийся
Записан
Zmeishe
Гость
« Ответ #31 : Апрель 10, 2008, 08:39 »

Ну некогда мне чистить его - реально некогда.
Предлагаю так - я цепляю два файла myheader.h и myheader.cpp и изучайте их.
По мере возникновения вопросов я буду коротко отвечать на конкретный кусок кода.
В конце концов его оптимизировать надо - вот совместными усилиями предлагаю его довести до совершенства.
PS: Если надумаете его Тролям слить - про меня не забудте (ну хотя бы упомянуть) Смеющийся
Записан
Karl-Philipp
Гость
« Ответ #32 : Апрель 10, 2008, 08:45 »

Ну некогда мне чистить его - реально некогда.
Предлагаю так - я цепляю два файла myheader.h и myheader.cpp и изучайте их.
По мере возникновения вопросов я буду коротко отвечать на конкретный кусок кода.
В конце концов его оптимизировать надо - вот совместными усилиями предлагаю его довести до совершенства.
PS: Если надумаете его Тролям слить - про меня не забудте (ну хотя бы упомянуть) Смеющийся


я - за! Улыбающийся
Записан
ритт
Гость
« Ответ #33 : Апрель 10, 2008, 13:27 »

Ну некогда мне чистить его - реально некогда.
Предлагаю так - я цепляю два файла myheader.h и myheader.cpp и изучайте их.
По мере возникновения вопросов я буду коротко отвечать на конкретный кусок кода.
В конце концов его оптимизировать надо - вот совместными усилиями предлагаю его довести до совершенства.
PS: Если надумаете его Тролям слить - про меня не забудте (ну хотя бы упомянуть) Смеющийся
Троллям я отправляю только свой код (а в данном случае Тролли и не заинтересуются данным решением как минимум в ближайшее время)

если ничего не мешает, скинь код в ЛС. использовать такой хидер мне пока негде, но ознакомиться с решением интересно (особенно, если у хидера не только скриншоты симпатичные Улыбающийся )
Записан
Zmeishe
Гость
« Ответ #34 : Апрель 10, 2008, 14:45 »

Вот архивчик на 3Кб. Скудные комментарии в кодировке UTF8
Записан
Zmeishe
Гость
« Ответ #35 : Апрель 14, 2008, 16:08 »

QSocketDataSet *cds - это модель - ессно моя модель.

QSocketDataSet это наследник от QDataSet, а QDataSet наследник от QAbstractTableModel.

Это я создавал смесь моделей Qt и билдеровского TClientDataSet.
В двух словах это трёхзвенка для работы с БД.

Сервер приложений тянет данные из БД и гонит по сокету на клиента
QSocketDataSet на клиенте вытягивает их из сокета. Для того, чтобы показывать это во вьюхах пришлось
скрестить с QAbstractTableModel и перекрыть некоторые функции.

Что касается сложных заголовков, то для них в QDataSet я добавил
QList указателей на поля Fields - это поля из таблицы БД.
и добавил
QList колумнов Columns это часть указателей Fields, которые надо показывать во вьюхах, но порядок у них там другой.

и их визуальные свойства
    QString p_title;
    int p_width;
    int p_displayScale;
    Qt::Orientation p_orientation;
    QString p_typeFormat;
    char p_format;
    bool p_hidden;   
    bool p_readOnly;
    bool p_checkBox;
    QString p_trueValue;
    QString p_falseValue;
    QStringList p_pickList;
    QColor p_color;
    int p_columnIndex;

Когда вьюхи обращаются к модели к функции data() через logicalIndex, я им подсовываю нужные свойства в зависимости от Роли.

Структура сложного заголовка хранится в QDataHeaderView: public QHeaderView в собственной модели headerModel = new QStandardItemModel(); и строится она на основании свойства p_title списка Columns.
« Последнее редактирование: Апрель 14, 2008, 18:59 от Zmeishe » Записан
Karl-Philipp
Гость
« Ответ #36 : Апрель 14, 2008, 17:00 »

cпасибо большое за описание
Записан
Karl-Philipp
Гость
« Ответ #37 : Апрель 15, 2008, 18:15 »

продолжаю раскуривать класс Улыбающийся
ну никак не выходит Грустный

попытался возобновить структуру классов таким образом:

Код:
class QSocketDataSet : public QAbstractItemModel
{
   Q_OBJECT
   QSocketDataSet( QObject * parent = 0 );
   ~QSocketDataSet();
private:
public:
   QList<Columns*> m_vColumns;
};

class Columns
{
public:
   Columns(int width, bool visibility, Qt::Orientation orientation, int columnIndex);
   ~Columns();

   int width() { return m_iWidth; }
   bool hidden() { return m_bHidden; }
   QString title() { return m_sTitle; }
   Qt::Orientation orientation() { return m_Orientation; }
protected:
private:
   QString m_sTitle;
   int m_iWidth;
   Qt::Orientation m_Orientation;
   bool m_bHidden;   
   int m_iColumnIndex;

};

Если правильно понял, то класс Columns - это класс с колонками самого верхнего уровня. Так ли это?

сделал такие конструкторы:

Код:
QSocketDataSet::QSocketDataSet( QObject * parent)
: QAbstractItemModel(parent)
{
Columns* section1 = new Columns( 100, false, Qt::Horizontal, 0);
m_vColumns.push_back( section1 );
}

Columns::Columns(int width, bool visibility, Qt::Orientation orientation, int columnIndex)
{
m_iWidth = width;
m_bHidden = visibility;
m_pOrientation = orientation;
m_sTitle = "parent column|child column1|child column2";
m_iColumnIndex = columnIndex;
}

соответствтенно в реализации QDataHeaderView заменил

Код:
cds->Fields->Columns[i]->...
на
Код:
cds->Columns[i]->

в методе paintSection()

Код:
QField *fld = cds->Fields->Columns[ logicalIndex ];
поменял на
Код:
Сolumns *fld = cds->Columns[ logicalIndex ];

единственное, что непонятно - в методе headerData содержится строчка

Код:
v_list.insert(0,  cds->Fields->Columns[ Section ]->fieldName());
что же возвращает метод fieldName, если title() возвращает m_sTitle?

и еще: никак не пойму, где используется свойство m_iColumnIndex?
Записан
Zmeishe
Гость
« Ответ #38 : Апрель 16, 2008, 08:02 »

Цитировать
единственное, что непонятно - в методе headerData содержится строчка

Код:
Код:
v_list.insert(0,  cds->Fields->Columns[ Section ]->fieldName());
что же возвращает метод fieldName, если title() возвращает m_sTitle?


Код:
	
   QVariantList v_list;
           if(orientation == Qt::Horizontal) // Если горизонтальный
{ // Вытащить инфу о хидере для Section, которая строится по title
getTreeItems(headerModel->invisibleRootItem(), &v_list, Section, &tmp_rows);
              if(v_list.count() == 0) // Если инфы о хидере по title нет, значит title забыли задать, либо НЕ посчитали нужным
         // Впихнуть туда SQL имя поля из БД
                    v_list.insert(0,  cds->Fields->Columns[ Section ]->fieldName());

return v_list;
}


Цитировать
и еще: никак не пойму, где используется свойство m_iColumnIndex?

Код:
class QField{
 ...
    QString p_title;
    int p_width;
    int p_displayScale;
    Qt::Orientation p_orientation;
    QString p_typeFormat;
    char p_format;
    bool p_hidden;   
    bool p_readOnly;
    bool p_checkBox;
    QString p_trueValue;
    QString p_falseValue;
    QStringList p_pickList;
    QColor p_color;
    int p_columnIndex;
...
}

class QFields {
...
   QList<QField*> Fields;
   QList<QField*> Columns;
...
}

class QDataSet: public QAbstractTableModel{
...
  QFields *Fields;
...
}
class QSocketDataSet: public QDataSet{
...
  // Порт, IP Сервера и т.д.
...
}
index поля в SQL таблице может быть 7, а во вьюхе оно будет, например, во 2-ой колонке.
для этого и нужен p_columnIndex, чтобы знать где оно отображается.
Иначе пришлось бы ещё заюзывать промежуточную Poxy Model.

« Последнее редактирование: Апрель 16, 2008, 08:41 от Zmeishe » Записан
Karl-Philipp
Гость
« Ответ #39 : Апрель 16, 2008, 09:31 »

я конечно извиняюсь за свою сообразительность, но нигде не могу найти метода, который бы использовал int p_columnIndex;
подозреваю, что это paintSection(), но как последний узнает об p_columnIndex Непонимающий

или, может, p_columnIndex не нужен для построения  хэдера, который нужно создать так, как это предлагается в QString p_title; ?
« Последнее редактирование: Апрель 16, 2008, 09:57 от terlan » Записан
Zmeishe
Гость
« Ответ #40 : Апрель 16, 2008, 09:57 »

p_columnIndex в визуальных компонентах вообще не используется.
У моих полей QField есть функция setValue(const QVariant & value) для того чтобы setData(...) модели не юзать.

Если я программно меняю значения полей типа:
while( ! dataSet->isEof() )
{
 ...
 myField->setValue("Бла-бла");
 dataSet->Next();
}

То ни одна вьюха об этом не узнает.

Для этого внутри функции setValue() я проверяю columnIndex, если он больше нуля, то поле входит в состав Columns и я вызываю setData() модели со своей личной Ролью только для того, чтобы там всего лишь выдать emit dataChanged(...);   
Все заинтересованные вьюхи, таблички, списки, комбобоксы сразу отобразят изменения.
Записан
Karl-Philipp
Гость
« Ответ #41 : Апрель 16, 2008, 10:58 »

спасибо за терпение Улыбающийся
вопрос конечно же не по теме, но указатель cds не может взять модель вот в этом месте:

Код:
void QDataHeaderView::slotCountChanged ( int oldCount, int newCount )
{
   QSocketDataSet *cds = qobject_cast<QSocketDataSet*>(model());       
   if(cds == NULL) return;
...
}

сds == NULL, а почему, если

Код:
class QSocketDataSet : public QAbstractItemModel
{
   Q_OBJECT
   QSocketDataSet( QObject * parent = 0 );
   ~QSocketDataSet();
private:
   QList<Field*> Columns;
};
« Последнее редактирование: Апрель 16, 2008, 11:13 от terlan » Записан
Zmeishe
Гость
« Ответ #42 : Апрель 16, 2008, 11:22 »

у вьюхи функция model() вовсе не обязательно может вернуть то, что потом можно привести к типу QSocketDataSet. 
Всё, что не QSocketDataSet меня не интересует, поэтому return;
Или что-то не так?
Записан
Karl-Philipp
Гость
« Ответ #43 : Апрель 16, 2008, 11:39 »

что-то не так:
сигнал sectionCountChanged(int, int) имитируется, но при выполнении
Код:
QDataHeaderView::slotCountChanged ( int oldCount, int newCount )
слота, почему-то указатель cds - нулевой, соответственно return;
только почему Непонимающий
« Последнее редактирование: Апрель 16, 2008, 11:45 от terlan » Записан
Zmeishe
Гость
« Ответ #44 : Апрель 16, 2008, 11:53 »

Если у QDataHeaderView модель будет какая угодно, но не QSocketDataSet,
конструкция
QSocketDataSet *cds = qobject_cast<QSocketDataSet*>(model());       
вернёт NULL или НЕ NULL ?
Я хочу подстраховаться и с другими моделями не работать. Кому нужны другие модели, пусть сам учитывает тонкости своих моделей. Я НЕ ставил себе цель рисовать эти заголовки в общем виде для любых моделей. Меня моя модель вполне устраивает.
Записан
Страниц: 1 2 [3] 4   Вверх
  Печать  
 
Перейти в:  


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