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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Выделение части ячейки в таблице (делегаты)  (Прочитано 3710 раз)
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« : Июнь 20, 2016, 15:22 »

У меня в таблице ячейки могут иметь два значения (иконки), которые могут отдельно выделяться.

Сделал делегат и для состояния выделения определял на какой половине ячейки находится курсор и менял положение рамки выделения,
но такая реализация оказалась с тормозами -- при переключении внутри ячейки видна задержка и если после клика на одну половину переместить курсор, то выделение может оказаться на другой половине


Мне нужна возможность выделения части ячейки с возможностью определять что выделено. В рабочем проекте использую: QTableView и QAbstractTableModel


Привожу код и архив с минимальным проектом.

celldelegate.h
Код
C++ (Qt)
#ifndef CELLDELEGATE_H
#define CELLDELEGATE_H
 
 
#include <QStyledItemDelegate>
 
class CellDelegate : public QStyledItemDelegate
{
   public:
       CellDelegate(QWidget* parent = 0);
 
   protected:
       void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
 
 
#endif // CELLDELEGATE_H
 

celldelegate.cpp
Код
C++ (Qt)
#include "celldelegate.h"
#include <QPainter>
#include <QDebug>
 
 
CellDelegate::CellDelegate(QWidget* parent)
   : QStyledItemDelegate(parent) {
 
}
 
void CellDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
   // Цвет выделения полупрозрачный, чтобы были видно что в ячейке
   QStyleOptionViewItem itemOption(option);
   initStyleOption(&itemOption, index);
 
   if (itemOption.state & QStyle::State_Selected) {
       QPoint pos = dynamic_cast <QWidget*> (parent())->mapFromGlobal(QCursor::pos());
       QRect& rect = itemOption.rect;
       bool leftSide = (rect.x() + (rect.width() / 2)) > pos.x();
 
       if (leftSide) {
           rect.setWidth(rect.width() / 2);
       } else {
           rect.setX(rect.x() + rect.width() / 2);
       }
 
       QColor color = itemOption.palette.color(QPalette::Highlight);
       color.setAlpha(180);
       itemOption.palette.setColor(QPalette::Highlight, color);
   }
 
   QStyledItemDelegate::paint(painter, itemOption, index);
}
 


widget.h
Код
C++ (Qt)
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QTableWidget>
 
 
class Widget : public QWidget
{
   Q_OBJECT
 
   public:
       Widget(QWidget *parent = 0);
 
   private:
       QTableWidget table;
};
 
#endif // WIDGET_H


widget.cpp
Код
C++ (Qt)
#include "widget.h"
#include <QVBoxLayout>
#include "celldelegate.h"
 
Widget::Widget(QWidget *parent)
   : QWidget(parent)
{
   QVBoxLayout* layout = new QVBoxLayout();
   layout->addWidget(&table);
 
   table.setSelectionBehavior(QAbstractItemView::SelectItems);
   table.setSelectionMode(QAbstractItemView::SingleSelection);
   table.setItemDelegate(new CellDelegate(table.viewport()));
 
   table.setRowCount(3);
   table.setColumnCount(3);
 
   setLayout(layout);
}
 
« Последнее редактирование: Июнь 21, 2016, 11:46 от gil9red » Записан

Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Июнь 21, 2016, 07:05 »

Ну использовать QCursor::pos вообще не годится - развалится хотя бы при скролле таблицы. Думается нужно запоминать индекс и "какая половинка" при нажатии и движении мыши (аттач)
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #2 : Июнь 21, 2016, 11:46 »

Igors, ваш вариант классный -- рабочий и без багов Улыбающийся

Я изначально ловил сигнал clicked и на него запоминал индекс, а в делегате уже из parent'а получал его, но возникали некоторые "артефакты". Потом уже работал с событиями mouse*


А почему вы использовали QPersistentModelIndex для хранения, а не QModelIndex, название QPersistentModelIndex кое о чем намекает, да и в доке говорится, что он более безопасно хранит, но проблем QModelIndex вроде бы не было замечено
« Последнее редактирование: Июнь 21, 2016, 11:54 от gil9red » Записан

Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Июнь 21, 2016, 12:12 »

А почему вы использовали QPersistentModelIndex для хранения, а не QModelIndex, название QPersistentModelIndex кое о чем намекает, да и в доке говорится, что он более безопасно хранит, но проблем QModelIndex вроде бы не было замечено
Напр грохнули содержимое таблицы - persistent станет невалидным, а обычный хз
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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