Qt實戰13.簡單通用的日誌輸出窗口


1 需求描述

設計一個類似於VS的日誌輸出窗口,點擊某一行後內容能夠自動展開,改變列寬時,選中行能夠根據日誌內容自動調整高度。同時提供一些常用的功能,例如複製、顯示/隱藏列、日誌分類顯示、顯示狀態恢復等。

2 設計思路

這是一個實際項目中的一個控制檯功能模塊,用於顯示日誌信息,日誌分爲錯誤、警告、消息三大類;當時主要考慮實現要儘可能簡單,所以優先想到了QTreeWidget、QTableWidget,使用QTreeWidget效果不大理想,主要是在選中行時和改變列寬時自動展開功能,在網上也查詢了一些方案,都不理想。
後來發現Qt提供的一個接口QTableView::resizeRowToContents,好了,一些由此展開。

3 代碼實現

這裏主要是通過繼承QTableWidget實現相關功能,爲了實現一定美觀,對TableWidget進行下簡單的設置:

    setShowGrid(false);
    setFocusPolicy(Qt::NoFocus);
    setSelectionBehavior(QAbstractItemView::SelectRows);
    setSelectionMode(QAbstractItemView::SingleSelection);
    setEditTriggers(QAbstractItemView::NoEditTriggers);

    verticalHeader()->setDefaultSectionSize(DEFAULT_SECTION_SIZE);

首先,關閉網格顯示;取消焦點,主要是屏蔽選中時的虛線框;
當然還要設置爲單選行、不可編輯模式;同時設置了一個默認的行高。
同時呢,選中行時我們需要設置下選中樣式,這裏用QSS處理下:

QTableWidget {
    selection-background-color: #3399ff;
    selection-color: white;
}

當某一行被選中後我們需要處理一下:

void OutputWidget::onCurrentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous)
{
    if (previous)
    {
        setRowHeight(this->row(previous), DEFAULT_SECTION_SIZE);
    }

    resizeRowToContents(this->row(current));
}

這裏設置一個默認的行高,當選中行改變時,上一次選中行恢復默認行高,當然也可以不處理,根據需求來。
當列寬改變時,我們也要做下處理:

    QHeaderView *header = horizontalHeader();
    header->setHighlightSections(false);
    connect(header, &QHeaderView::sectionResized, [=]() {
        QTableWidgetItem *currentItem = this->currentItem();
        if (!currentItem)
        {
            return;
        }
        resizeRowToContents(this->row(currentItem));
    });

這裏主要通過監聽QHeaderView的sectionResized信號實現。
好啦,按邏輯來講到這裏應該就可以了,但是使用過程中發現一點點問題,選中行改變時可能會串,額外處理下:

    connect(this, &OutputWidget::itemPressed, this, [=](QTableWidgetItem *item) {
        setCurrentItem(item);
    });

到此,基本功能就實現了,其他功能需要自行拓展,或者聯繫我定製開發,哈哈。

4 總結

大道至簡,編程也一樣,在滿足需求的情況下,實現要儘可能簡單,Qt提供的一些便捷類,例如QListWidget、QTreeWidget、QTableWidget等是能夠滿足絕大多數使用場景的。一般來說,真實的使用場景也並不會有多複雜,是我們想得太複雜而已。

5 下載

示例代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章