1. 程式人生 > >Qt之QTableView 滑鼠動作特效

Qt之QTableView 滑鼠動作特效

之前有講解過QTableWidget的使用(QTableWidget詳解(樣式、右鍵選單、表頭塌陷、多選等)),已經算是很詳細了,這節再講更常用的檢視部件QTableView的高階用法。

    Qt中有幾種純粹的檢視部件:QListView、QTableView、QColumnView、QTreeView,所有的這些檢視都必須提供一個模型(無論是自定義,還是Qt中已提供的)來與之配合。Qt仍然提供了一些便利的視窗部件(“便利”是因為它們提供了自己內建的模型,並能直接使用),如;QListWidget、QTableWidget、和QTreeWidget。還有QComboBox,既是一個便利的視窗部件也是一個檢視部件,也就是說,我們既可以直接使用(因為它提供了內建的模型),也能把它當做一個模型的檢視部件(這種情況下,可以提供一個合適的模型給它)。

    之所以說檢視部件常用,是因為在程式設計的過程當中經常遇到大資料集,使用檢視/模型就顯得更有效率。當然,對於資料集較小(數百或數千個項)的應用程式,選擇便利部件比較合適。

    這節不再去過多的講解模型/檢視如何使用(Qt之模型/檢視(實時更新資料)一節有特別介紹),更多的是討論QTableView的深入用法。

一、實現QToolTip

1.設定滑鼠跟隨

table_view->setMouseTracking(true); 

2.實現自定義槽函式

void TableView::showToolTip(const QModelIndex &index)
{
        if(!index.isValid())
                return;

        int row = index.row();
        QString file_name = list_file.at(row);

        if(file_name.isEmpty())
                return;

        QToolTip::showText(QCursor::pos(), file_name); 
}

3.連線訊號與槽

connect(this, &TableView::entered, this, &TableView::showToolTip); 

效果如下:

Qt之QTableView

二、整行選中(去掉選中時的虛線),並設定選中色

1.設定整行選中

table_view->setSelectionBehavior(QAbstractItemView::SelectRows); 

2.實現自定義委託(QStyledItemDelegate)

void StyledDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const  
{  
        QStyleOptionViewItem  view_option(option);  
        if (view_option.state & QStyle::State_HasFocus) {  
                view_option.state = view_option.state ^ QStyle::State_HasFocus;  
        }

        QStyledItemDelegate::paint(painter, view_option, index);
}

3.設定委託

table_view->setItemDelegate(styled_delegate);

4.使用QSS設定選中色

QTableView{
        border:none;
        background:white;
}
QTableView::item:selected{
        color:white;
        background:rgb(34, 175, 75);    
}

效果如下:

Qt之QTableView

三、設定滑鼠滑過顏色

1.滑鼠滑過某item項高亮(自定義代理裡面新增滑過樣式)

void StyledDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const  
{  
        QStyleOptionViewItem  view_option(option);  
        if (view_option.state & QStyle::State_HasFocus) {  
                view_option.state = view_option.state ^ QStyle::State_HasFocus;  
        }

        //新增滑鼠滑過的背景色
        if(option.state & QStyle::State_MouseOver){
                painter->fillRect(view_option.rect, QColor(180, 200, 220));
        }

        QStyledItemDelegate::paint(painter, view_option, index);
}  

效果如下:

Qt之QTableView
 

    這種情況下,可以看出,當滑鼠滑過某個item項的時候,改項會改變顏色,但選中的時候是整行選中,則看起來很不協調,下面將講述如何實現滑鼠滑過後整行高亮效果。

2.滑鼠滑過整行高亮

自定義檢視中實現以下幾個方法:

void TableView::mouseMoveEvent ( QMouseEvent * event)

{
        int row = indexAt(event->pos()).row();
        updateRow(row);
}
void TableView::leaveEvent ( QEvent * event )

{
        table_model->setHoverRow(-1);

    int column_count= model()->columnCount();
        for (int i = column_count- 1; i >= 0; i--)
        {
                update(model()->index(current_row, i));
        }
        current_row = -1;
}
void TableView::updateRow(int row)

{
        if (row == current_row)
                return;

        table_model->setHoverRow(row);

   int column_count= model()->columnCount();
        for (int i = column_count- 1; i >= 0; i--)
        {
                update(model()->index(current_row, i));
                update(model()->index(row, i));
        }
        table_model->showToolTip(row);  //自定義方法用來進行QToolTip的顯示
        current_row = row;
}

自定義模型中實現以下幾個方法:

void TableModel::setHoverRow(int hover_row)

{
        this->hover_row = hover_row;
}
QVariant ConvertPdfModel::data(const QModelIndex &index, int role) const
{
        if (!index.isValid())
                return QVariant();

        int row = index.row();  //行號
        if (row < 0 || row >= list_file.size())
                return QVariant();

        int column = index.column();
        QString name = list_file.at(row);
        switch (role) {
        case Qt::BackgroundColorRole:{
                        if (row == hover_row) {
                                return QColor(180, 200, 220);
                        }
                }
        case Qt::DecorationRole: {  //圖示
                        //...
                }
        case Qt::DisplayRole: {  //文字
                        //...
                }
        case Qt::TextAlignmentRole: {  //對齊方式
                        //...
                }
        default:
                return QVariant();
        }

        return QVariant();
}

效果如下:

Qt之QTableView

    updateRow主要是進行顏色更新的,滑鼠所在行號若與之前的行號保持一致(滑鼠一直處於當前行),則直接返回,否則(行號改變),進行更新。mouseMoveEvent、leaveEvent主要處理滑鼠移動、離開過程中的邏輯 —— 然後呼叫updateRow函式進行實時更新。

總結:   

    以上針對QTableView做了高階、深入的講解,加上之前章節對模型/檢視的詳細用法的介紹,大家應該對這些控制元件有了更深入的瞭解,並能更好的使用它們。關於如何處理更為細節的問題,根據這些介紹也能悟出一二,所有的東西都不能盡善盡美,留下的小細節就在實戰中慢慢摸索,也許只有遇到困難時,你才會發現還有進步的空間。。。