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

示例代码

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