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 下載

示例代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM