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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QItemDelegate выделение текста надписи при фильтрации  (Прочитано 4170 раз)
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« : Сентябрь 05, 2016, 17:12 »

Есть модель, у нее есть прокси модель, в которой реализован метод фильтрации
Код:
void filterAcceptsRow(int , const QModelIndex);

Кликаем по вьюшки вылетает окно фильтра (filterWidget)
Код
C++ (Qt)
 
void TableView::mouseDoubleClickEvent(QMouseEvent *event)
{
   if(event->button() == Qt::RightButton){
       if(filterWidget != NULL){
           delete  filterWidget;
           filterWidget = NULL;
       }
 
       QString nameTable = ((SqlTableModel*)(((DataBaseFilterModel*)model())->sourceModel()))->getNameTable();
       filterWidget = new FilterWidget(nameTable,nameColumn,column,0);
       connect(filterWidget,SIGNAL(changeFilter(QString ,int)),((DataBaseFilterModel*)model()),SLOT(updateFilterColumn(QString ,int)));
       connect(filterWidget,SIGNAL(closeWidget()),this,SLOT(closeFilterWidget()));
       filterWidget->show();
 
   }
 
   QTableView::mouseDoubleClickEvent(event);
}
 

при изменении текста в нем - фильтр прокси обновляется соответственно
вот сам фильтр-виджет
Код
C++ (Qt)
FilterWidget::FilterWidget(QString nameTable ,QString nameColumn, int numColumn, QWidget *parent) :
   QWidget(parent),
   ui(new Ui::FilterWidget)
{
   qDebug()<<__FUNCTION__;
 
   ui->setupUi(this);
 
   setWindowTitle(nameTable);
   ui->nameColumn->setText(nameColumn);
 
   filter.clear();
   column = numColumn;
 
   connect(ui->leFilter,SIGNAL(textChanged(QString)),this,SLOT(setTextFilter(QString )));
}
 
FilterWidget::~FilterWidget()
{
   qDebug()<<__FUNCTION__;
   delete ui;
}
 
void FilterWidget::closeEvent(QCloseEvent *event)
{
   qDebug()<<__FUNCTION__;
   Q_EMIT closeWidget();  
   QWidget::closeEvent(event);
}
 
void FilterWidget::setTextFilter(QString string)
{
   filter.clear();
   filter.append(string);
 
   Q_EMIT changeFilter(filter,column);
}
 

и  update фильтра для прокси

Код
C++ (Qt)
void DataBaseFilterModel::updateFilterColumn(QString string, int column)
{
   keyColumn = column;
   strFilter.clear();
   strFilter.append(string);    
   invalidateFilter();
}
 

Все работает замечательно.
Хочу подсвечивать текст при работе фильтра.
Добавляю делегата в проксю.

Код
C++ (Qt)
LineEditDelegate::LineEditDelegate(QObject *parent):
   QItemDelegate(parent)
{
}
 
LineEditDelegate::~LineEditDelegate()
{
}
 
QWidget *LineEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   if(index.column() == 1){
       QLineEdit *lineEdit = new QLineEdit(parent);
       return lineEdit;
   }
   return  QItemDelegate::createEditor(parent,option,index);
}
 
void LineEditDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
   if(index.column() == 1){
       QString string = index.model()->data(index,Qt::EditRole).toString();
       QLineEdit *le = static_cast<QLineEdit* >(editor);        
       le->setText(string);
   }
}
 
void LineEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
  if(index.column() == 1){
      QLineEdit *le = static_cast<QLineEdit* >(editor);
      QString str = le->text();
      model->setData(index,str,Qt::EditRole);
   }
}
 
void LineEditDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   editor->setGeometry(option.rect);
}
 
void LineEditDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   QString strFilter = ((DataBaseFilterModel*)(index.model()))->getStringFilter();
   const QModelIndex src = ((DataBaseFilterModel*)(index.model()))->mapToSource(index);
 
   qDebug()<<"paint";
 
   if(index.column() == 1 && !strFilter.isEmpty() && ((DataBaseFilterModel*)(index.model()))->filterAcceptsRow(src.row(),QModelIndex())){
       QFontMetrics fm(option.font);
       int h_cell = option.rect.height();
       int h_text = fm.boundingRect(strFilter).height();
       int w_text = fm.boundingRect(strFilter).width();
 
 
       painter->setPen(QPen("yellow"));
       painter->setBrush(QBrush("yellow"));
       painter->drawRect(option.rect.x(),option.rect.y() + ((h_cell-h_text)/2),w_text,h_text);
 
   }
   return QItemDelegate::paint(painter,option,index);
}
 
 

При изменении фильтра инфа фильтруется при этом окно фильтра активно!
Но текст не выделен при этом.
Как только окно с вьюшкой делаю активным, текст выделен. Такое впечатление, что делегат не перерисовывается.
Почему Непонимающий


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

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Сентябрь 06, 2016, 11:22 »

Попробуй вместо invalidateFilter() вызвать invalidate().
Записан

Qt 5.11/4.8.7 (X11/Win)
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #2 : Сентябрь 06, 2016, 12:31 »

Попробуй вместо invalidateFilter() вызвать invalidate().

Спасибо заработало!!! А в чем фишка???  Непонимающий
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Сентябрь 06, 2016, 12:44 »

Спасибо заработало!!! А в чем фишка???  Непонимающий
По непонятной мне причине при invalidateFilter() модель не испускает ни одного сигнала.
Соответственно вьюха не обновлялась.
invalidate() испускает layoutChanged(), на который завязана вьюха.
Но надо иметь в виду, что вызов invalidate() может быть довольно-таки тяжелым.
Вполне возможно, что намного легче из updateFilterColumn() испустить свой сигнал типа filterColumnUpdated() и за-коннектить к нему TableView::viewport()->update().
Записан

Qt 5.11/4.8.7 (X11/Win)
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #4 : Сентябрь 06, 2016, 13:02 »

Вполне возможно, что намного легче из updateFilterColumn() испустить свой сигнал типа filterColumnUpdated() и за-коннектить к нему TableView::viewport()->update().

Что не нашел такого метода viewport() в QTableView
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Сентябрь 06, 2016, 14:27 »

Код
C++ (Qt)
QWidget* QAbstractScrollArea::viewport() const
Записан

Qt 5.11/4.8.7 (X11/Win)
demaker
Птица говорун
*****
Offline Offline

Сообщений: 960


Просмотр профиля
« Ответ #6 : Сентябрь 06, 2016, 18:45 »

Код
C++ (Qt)
QWidget* QAbstractScrollArea::viewport() const


Спасибо работает и через сигнал-слот!
« Последнее редактирование: Сентябрь 06, 2016, 22:04 от demaker » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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