Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: mal от Март 05, 2009, 10:48



Название: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: mal от Март 05, 2009, 10:48
Переехал с 4.4.3 на текущую версию qt  и обнаружил такой косяк subj.
В дебаге  проверил, что при создании объекта  соединение устанавливается

Код:
qtablewidget.cpp
*
void QTableWidgetPrivate::setup()
{
    Q_Q(QTableWidget);
    // view signals
...
    QObject::connect(q, SIGNAL(doubleClicked(QModelIndex)),
                     q, SLOT(_q_emitItemDoubleClicked(QModelIndex)));
...
}

однако сколь не даблкликай по виджету, сигнал в слот сорса
Код:
void QTableWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
{
    Q_Q(QTableWidget);
    if (QTableWidgetItem *item = model()->item(index))
        emit q->itemDoubleClicked(item);
    emit q->cellDoubleClicked(index.row(), index.column());
}
не приходит
Ну и соответственно, не ловятся в моем классе соббытия itemDoubleClicked и cellDoubleClicked, а надо.
Есть соображения?

ЗЫ сигнал itemClicked испускается и моим объектом ловится, но сильно нужен и doubleClick, который ранее работал.


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: pastor от Март 05, 2009, 11:44
Выкладывай минимальный компилябельный код, проверим у себя


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: mal от Март 05, 2009, 12:22
Проверил  - если создаешь свежее приложение - все сигналы ловятся.
Ожидалось , что при переезде снизу вверх, приложение работающее в предыдущей версии будет работать, как минимум не хуже.
Еще поковыряюсь сам - кастрировать свой глобальный проект занятие не из приятных. :-)
*
а вот и локализовал место, но пока не понял как с ним побороться:
пока таблица чистая сообщения генерятся и ловятся.

Для нормальной сортировки данных я переопределил  оператор< у наследника QTableWidgetItem:
h-file объекта QTableWidget
Код:
...
//Для возможности сортировки
class CMyTableWidgetItem1 : public QTableWidgetItem
{
bool operator<(const QTableWidgetItem &other) const;
};
...

и по мере поступления данных заполняю ими таблицу:
Код:
...
CMyTableWidgetItem1 *p_file_name = NULL;
p_file_name = (CMyTableWidgetItem1*)new QTableWidgetItem(QString("тут имя файла"));
p_file_name->setFlags(Qt::ItemIsSelectable);
if(p_file_name)
    p_tbl->setItem(n_row, 0, p_file_name);
...

после заполнения данных таблица перестает генерить события doubleClick.  :(
Но в 4.4.3 этот код прекрасно работал  ??? .
Видимо теперь буду ковыряться QTableWidgetItem


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: Alex03 от Март 05, 2009, 18:36
Код:
CMyTableWidgetItem1 *p_file_name = NULL;
p_file_name = (CMyTableWidgetItem1*)new QTableWidgetItem(QString("тут имя файла"));
p_file_name->setFlags(Qt::ItemIsSelectable);
if(p_file_name)
    p_tbl->setItem(n_row, 0, p_file_name);
Оригинальный код....
А по нормальному не судьба написать?
Код:
CMyTableWidgetItem1 *p_file_name = new CMyTableWidgetItem1(QString("тут имя файла"));
p_file_name->setFlags(Qt::ItemIsSelectable);
p_tbl->setItem(n_row, 0, p_file_name);
Проверка тоже не нужна скорее всего, ибо new без nothrow нулевой указатель вряд ли вернёт.


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: mal от Март 05, 2009, 18:46
критеку Александру :-)

в оригинальном коде все это крутится в try-блоке ( хотя проверка на создание айтема конешно рудимент )

Код:
for(int i=0; i < n_row_count; i++)
{
CMyTableWidgetItem1*p_file_name = NULL;
CMyTableWidgetItem1*p_card_number = NULL;
CMyTableWidgetItem1*p_lat_number = NULL;
CMyTableWidgetItem1*p_kind_crime = NULL;
CMyTableWidgetItem1*p_priority = NULL;
CMyTableWidgetItem1*p_time = NULL;
CMyTableWidgetItem1*p_type = NULL;
//имя файла без пути и расширения
try
{
p_file_name = (CMyTableWidgetItem1*)new QTableWidgetItem(QString(local_list.at(i).fileName()));
p_file_name->setFlags(Qt::ItemIsSelectable);
if(p_file_name)
p_tbl->setItem(n_row, 0, p_file_name);
// и дальше создание остальных n-айтемов с другими данными текущей строки таблицы
...
}
catch(...)
{
err_mem();
reject();
}
}


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: Alex03 от Март 05, 2009, 18:50
ключевая фраза - замена
new QTableWidgetItem();
на
new CMyTableWidgetItem1();


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: mal от Март 06, 2009, 07:50
Александр таки оказался прав.  :o

Неясно только, почему такая конструкция корректно отрабатывалась в более ранних версиях qt.  ???
Оригинальность кода, вызвавшая восторг у Александра была вызвана  тем, что проект пару лет работал с базовым классом т.е.
Код:
QTableWidgetItem1 *p_file_name = NULL;
p_file_name = new QTableWidgetItem(QString(...));
Когда мне потребовалось переопределить сортировку, ввел свой класс, но для колонки с именем файла в лоб  этого сделать не удалось ибо конструкция
Код:
CMyTableWidgetItem1 *p_file_name = NULL;
p_file_name = new CMyTableWidgetItem1(QString(...));
не проходила вызывая ошибку компилятора
error C2664: 'CMyTableWidgetItem1::CMyTableWidgetItem1(const CMyTableWidgetItem1 &)' : cannot convert parameter 1 from 'QString' to 'const CMyTableWidgetItem1 &'

остальные, элементы таблицы создавались пустыми и потом распарсивании данных в них добавлялся текст
Код:
p_card_number = new CMyTableWidgetItem1();
p_tbl->setItem(n_row, 1, p_card_number);
...
p_card_number->setText(QString(str_val));

При вводе сортировки я не стал заморачиваться с ошибкой а сделал, то что умилило Александра
p_file_name = (CMyTableWidgetItem1*)new QTableWidgetItem(QString(local_list.at(i).fileName()));

Теперь поправил код для колонки с именем файла
Код:
CMyTableWidgetItem1 *p_file_name = NULL;
p_file_name = new CMyTableWidgetItem1();
p_file_name->setText(QString(local_list.at(i).fileName()));
p_tbl->setItem(n_row, 0, p_file_name);

И счастье настало - doubleClick в таблице вернулся.

Однако в 4.4.3  doubleClick таблицы работает (я настаиваю  :) ) при использовании моей "ошибочной" конструкции, а в 4.5.0 нет.  ???

ЗЫ Спасибо Александр. Точи кручки...  ;)


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: Rcus от Март 06, 2009, 07:53
Что прямо вот и сортировка даже работала без кастов?
С2664 меня умиляет, радует и огорчает одновременно.


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: mal от Март 06, 2009, 08:45
вот код оператора - все работало...
Код:
bool CMyTableWidgetItem1::operator<(const QTableWidgetItem &other) const
{
    const QVariant l = data(Qt::DisplayRole), r = other.data(Qt::DisplayRole);
switch(l.type())
{
case QVariant::Invalid:
  return (r.type() == QVariant::Invalid);
case QVariant::Int:
  return l.toInt() < r.toInt();
case QVariant::UInt:
  return l.toUInt() < r.toUInt();
case QVariant::LongLong:
  return l.toLongLong() < r.toLongLong();
case QVariant::ULongLong:
  return l.toULongLong() < r.toULongLong();
case QVariant::Double:
  return l.toDouble() < r.toDouble();
case QVariant::Char:
  return l.toChar() < r.toChar();
case QVariant::Date:
  return l.toDate() < r.toDate();
case QVariant::Time:
  return l.toTime() < r.toTime();
case QVariant::DateTime:
  return l.toDateTime() < r.toDateTime();
case QVariant::String:
default:
  return l.toString().compare(r.toString(), Qt::CaseSensitive) < 0;
}
return l.toString() < r.toString();
}


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: Alex03 от Март 06, 2009, 09:15
Тоже думаю (уверен) что сортировка не работала.
Точнее она работала, но стандартная.

Код operator<() тоже оригинальный, нафига всё перечислять?
Код:
    if(l.type() != someType)
    {
        return QTableWidgetItem::operator<(other);
    }
    return result_of_compare_someType;


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: mal от Март 06, 2009, 09:42
ну теперь вот совсем докопался до истины:
была у меня еще такая строчка кода сразу после создания QTableWidgetItem'a:
Код:
p_file_name->setFlags(Qt::ItemIsSelectable);

комментарим ее,  и doubleClick есть в 4.5.0 независимо от того, извращенно создан QTableWidgetItem или нет  :)

Александру

смотрим src/gui/itemviews/qtablewidget.cpp

Код:
bool QTableWidgetItem::operator<(const QTableWidgetItem &other) const
{
    const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole);
    if (QTableModel::canConvertToDouble(v1) && QTableModel::canConvertToDouble(v2))
        return v1.toDouble() < v2.toDouble();
    return v1.toString() < v2.toString();
}
Сортировку пришлось переопределять, потому что стандартная функция сортировки некорректно работала с датами и временем. Даже если ты уверен, что сортировка работала с первой колонкой стандартная - мне от того плохо не было. Главное, что корректно сортировалась колонка с датами.
А то, как этот оператор мной написан один раз и лежит себе где то тихонечко - опять таки мое дело. Ты ошибки критикуй, а не стиль кодирования.   ;)


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: Rcus от Март 06, 2009, 10:49
Странная реакция на критику. Апкаст в стиле C с надеждой на то что объект поменяет свой тип это не стиль, а wtf. То что ваш код где-то написан, но не выполняется из-за ошибки в другом месте может стать головной болью другого программиста в будущем. Более того, код копирующий стандартные функции заставляет тратить дополнительное время на его изучение.
/*ушел в подземелье ковырять доставшуюся в наследство CRM и проклинать создателя*/

Код
C++ (Qt)
   QDateTime dt = QDateTime::currentDateTime();
   QDateTime dt2 = QDateTime::currentDateTime().addDays(-3);
   qDebug()<<dt.toString(Qt::SystemLocaleShortDate)<<dt2.toString(Qt::SystemLocaleShortDate);
   qDebug()<<QVariant(dt).toString()<<QVariant(dt2).toString();
   qDebug()<<(QVariant(dt).toString()<QVariant(dt2).toString());

Код:
"06.03.2009 12:39:18" "03.03.2009 12:39:18"
"2009-03-06T12:39:18" "2009-03-03T12:39:18"
false
Все нормально работает с датами.


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: mal от Март 06, 2009, 11:26
RCus
- оно может быть и нормально работает, но вот стандартная сортировка столбца с датами в QTableWidget: 
 вложение файлы  - up и down;
 и с переопределенным оператором <   - up1 и down1


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: Rcus от Март 06, 2009, 12:24
/*sigh*/
proof?


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: mal от Март 06, 2009, 14:12
Rcus -  я проверил твой пример - замечательно сортируется.
Тем не менее проблема с сортировкой дат в QTableWidget возникала ранее не у меня одного.
Например :
http://www.prog.org.ru/topic_2984_0.html

Очень сожалею, что не могу выложить сюда свой проект целиком и полностью.

break?


Название: Re: Qt 4.5.0 - QTableWidget не ловит doubleClick
Отправлено: Rcus от Март 06, 2009, 14:17
Ну и там была та же проблема: сравнивались не даты, а их строковые представления. Понимаю что проще создать QTableWidgetItem присвоив текст в конструкторе, не используя метод setData + Qt::DisplayRole /*но все же factory method ftw*/.