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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Qt 4.5.0 - QTableWidget не ловит doubleClick  (Прочитано 11211 раз)
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, который ранее работал.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #1 : Март 05, 2009, 11:44 »

Выкладывай минимальный компилябельный код, проверим у себя
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
mal
Гость
« Ответ #2 : Март 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
« Последнее редактирование: Март 05, 2009, 18:14 от mal » Записан
Alex03
Гость
« Ответ #3 : Март 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 нулевой указатель вряд ли вернёт.
Записан
mal
Гость
« Ответ #4 : Март 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();
}
}
« Последнее редактирование: Март 05, 2009, 18:53 от mal » Записан
Alex03
Гость
« Ответ #5 : Март 05, 2009, 18:50 »

ключевая фраза - замена
new QTableWidgetItem();
на
new CMyTableWidgetItem1();
Записан
mal
Гость
« Ответ #6 : Март 06, 2009, 07:50 »

Александр таки оказался прав.  Шокированный

Неясно только, почему такая конструкция корректно отрабатывалась в более ранних версиях 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 нет.  Непонимающий

ЗЫ Спасибо Александр. Точи кручки...  Подмигивающий
Записан
Rcus
Гость
« Ответ #7 : Март 06, 2009, 07:53 »

Что прямо вот и сортировка даже работала без кастов?
С2664 меня умиляет, радует и огорчает одновременно.
« Последнее редактирование: Март 06, 2009, 08:04 от Rcus » Записан
mal
Гость
« Ответ #8 : Март 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();
}
« Последнее редактирование: Март 06, 2009, 08:53 от mal » Записан
Alex03
Гость
« Ответ #9 : Март 06, 2009, 09:15 »

Тоже думаю (уверен) что сортировка не работала.
Точнее она работала, но стандартная.

Код operator<() тоже оригинальный, нафига всё перечислять?
Код:
    if(l.type() != someType)
    {
        return QTableWidgetItem::operator<(other);
    }
    return result_of_compare_someType;
Записан
mal
Гость
« Ответ #10 : Март 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();
}
Сортировку пришлось переопределять, потому что стандартная функция сортировки некорректно работала с датами и временем. Даже если ты уверен, что сортировка работала с первой колонкой стандартная - мне от того плохо не было. Главное, что корректно сортировалась колонка с датами.
А то, как этот оператор мной написан один раз и лежит себе где то тихонечко - опять таки мое дело. Ты ошибки критикуй, а не стиль кодирования.   Подмигивающий
« Последнее редактирование: Март 06, 2009, 09:55 от mal » Записан
Rcus
Гость
« Ответ #11 : Март 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
Все нормально работает с датами.
Записан
mal
Гость
« Ответ #12 : Март 06, 2009, 11:26 »

RCus
- оно может быть и нормально работает, но вот стандартная сортировка столбца с датами в QTableWidget: 
 вложение файлы  - up и down;
 и с переопределенным оператором <   - up1 и down1
Записан
Rcus
Гость
« Ответ #13 : Март 06, 2009, 12:24 »

/*sigh*/
proof?
Записан
mal
Гость
« Ответ #14 : Март 06, 2009, 14:12 »

Rcus -  я проверил твой пример - замечательно сортируется.
Тем не менее проблема с сортировкой дат в QTableWidget возникала ранее не у меня одного.
Например :
http://www.prog.org.ru/topic_2984_0.html

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

break?
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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