Qt浅谈之四十四动态显示日志(QGraphicsItem)

一、简介

        在QGraphicsItem中使用QGraphicsItemAnimation和QTimeLine来实现动画的显示。其中的数据都是测试数据,仅为显示动画效果。

二、详解

1、部分代码

(1)LogMessagesItem.h
#ifndef _LOGMESSAGEITEM_H_
#define _LOGMESSAGEITEM_H_
#include <QtGui>
#include <QtCore>
#include "clusterpagenumber.h"
#include "calendarselected.h"

class LogContentItem;
class LogMessagesItem : public QObject, public QGraphicsItem
{
    Q_OBJECT
public:
    explicit LogMessagesItem(QGraphicsItem *parent = 0);
    QRectF boundingRect() const;
    void setSize(const int width, const int height);

protected:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    bool eventFilter(QObject *obj, QEvent *event);

private:
    void getLogContents();
    void showLogs();
    void hideLogItem();

private:
    int _width;
    int _height;
    int totalLogs;
    int totalPageNumber;
    int currentPageNumber;

    ClusterPageNumber *pageNumber;
    CalendarSelected *calendar;
    QList<LogContentItem *>logItem;
    QGraphicsRectItem *rectItem;
    bool leftToRight;

private slots:
    void slotCalendarFinish();
    void slotLogPageChange(int index);
};

class LogContentItem : public QGraphicsItem
{
public:
    explicit LogContentItem(QGraphicsItem *parent = 0);
    ~LogContentItem();
    QRectF boundingRect() const;
    void setData(const QList<QString> &data);

protected:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
private:
    QGraphicsTextItem *timeText;
    QGraphicsTextItem *typeText;
    QGraphicsTextItem *stateText;
    QGraphicsTextItem *describeText;
};
#endif
(2)LogMessagesItem.cpp
#include "LogMessagesItem.h"
#define MAXLOGSRPERPAGE 4

LogMessagesItem::LogMessagesItem(QGraphicsItem *parent)
    : QGraphicsItem(parent)
    , totalLogs(0)
    , totalPageNumber(1)
    , currentPageNumber(1)
    , leftToRight(true)
{
    _width = 633;
    _height = 437;
    logItem.clear();
    setFiltersChildEvents(true);
    calendar = new CalendarSelected;
    QGraphicsProxyWidget *calendarProxy = new QGraphicsProxyWidget(this);
    calendarProxy->setWidget(calendar);
    calendarProxy->setPos(10, 10);
    calendarProxy->show();
    calendarProxy->setZValue(1);
    connect(calendar, SIGNAL(finish()), this, SLOT(slotCalendarFinish()));

    pageNumber = new ClusterPageNumber;
    //pageNumber->setBackgroundColor(QColor("#FF0000"));
    pageNumber->resize(248, 18);
    pageNumber->setTitle(tr("合计日志条数"), 0);
    pageNumber->setCurrentAndTotalPage(1, 10);
    QGraphicsProxyWidget *pageNumberProxy = new QGraphicsProxyWidget(this);
    pageNumberProxy->setWidget(pageNumber);
    pageNumberProxy->setPos(633 - 248 -10, 437 - 35);
    pageNumberProxy->show();
    connect(pageNumber, SIGNAL(currentPageChanged(int)), this, SLOT(slotLogPageChange(int)));

    QGraphicsTextItem *title = new QGraphicsTextItem(this);
    title->setDefaultTextColor(QColor("#666666"));
    title->setFont(QFont("arial", 10, QFont::Normal));
    title->setPlainText(tr("按状态:"));
    title->setPos(460, 10);

    QComboBox *logListBox = new QComboBox;
    logListBox->resize(100, 23);

    logListBox->setStyleSheet("QComboBox{border:1px solid #d7d7d7; border-radius: 3px; padding: 1px 18px 1px 3px;} "
                          "QComboBox:editable{ background: white; }"
                          "QComboBox:!editable{ background: #fbfbfb; color:#666666}"
                          "QComboBox::drop-down{ subcontrol-origin: padding; subcontrol-position: top right; width: 22px; border-left-width: 1px; border-left-color: #c9c9c9; border-left-style: solid; /* just a single line */ border-top-right-radius: 3px; /* same radius as the QComboBox */ border-bottom-right-radius: 3px; }"
                          "QComboBox::down-arrow { image: url(:/resources/images/input_drop_down.png); }"
                          "QComboBox::down-arrow:on { /* shift the arrow when popup is open */ top: 1px; left: 1px;}"
                          "QComboBox QAbstractItemView::item{max-width: 30px;min-height: 20px}");

    QListView *listView = new QListView;
    listView->setStyleSheet("QListView{font-size: 11px}"
                           " QListView::item:!selected{color: #19649f}"
                            "QListView::item:selected:active{background-color: #1275c3}"
                            "QListView::item:selected{color: white}");

    logListBox->setView(listView);

    logListBox->addItem(tr("所有日志"));
    logListBox->addItem(tr("错误日志"));
    logListBox->addItem(tr("警告日志"));
    QGraphicsProxyWidget *listBoxrProxy = new QGraphicsProxyWidget(this);
    listBoxrProxy->setWidget(logListBox);
    listBoxrProxy->setPos(522, 12);
    listBoxrProxy->setZValue(1);
    listBoxrProxy->show();

    rectItem = new QGraphicsRectItem(QRectF(0, 0, 610, 85*4), this);
    rectItem->setPos(12, 45);
    rectItem->setPen(Qt::NoPen);
    rectItem->setFlag(QGraphicsItem::ItemClipsChildrenToShape,true);

    getLogContents();
}

QRectF LogMessagesItem::boundingRect() const
{
    return QRectF(0,0, _width, _height);
}

void LogMessagesItem::setSize(const int width, const int height)
{
    _width = width;
    _height = height;
}

void LogMessagesItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
}

bool LogMessagesItem::eventFilter(QObject *obj, QEvent *event)
{
    if (obj != calendar && event->type() == QEvent::MouseButtonPress) {
        this->clearFocus();
        calendar->setHideQDialog();
        return true;
    }
    if (event->type() == QEvent::Hide) {
        calendar->setHideQDialog();
    }
    if (event->type() == QEvent::Show) {
    }
    return QObject::eventFilter(obj, event);
}

void LogMessagesItem::getLogContents()
{
    for (int i =0; i < 22; i++) {
        QList<QString> data;
        data.append("2015-02-13 12:08:57");
        data.append("新建系统");
        data.append("系统创建完毕");
        data.append(tr("成功创建系统(%1)").arg(i + 1));
        LogContentItem *contentItem = new LogContentItem(rectItem);
        contentItem->setData(data);
        contentItem->hide();
        logItem.append(contentItem);
    }
}

void LogMessagesItem::showLogs()
{
    totalLogs = logItem.count();
    //totalLogs = 22;
    totalPageNumber = 6;
    //currentPageNumber = 1;
    hideLogItem();

    pageNumber->setTitle(tr("合计日志条数"), 22);
    pageNumber->setCurrentAndTotalPage(currentPageNumber, 6);

    LogContentItem *item = NULL;
    int index = (currentPageNumber - 1)*MAXLOGSRPERPAGE;
    for(int number = 0; index < totalLogs && index < currentPageNumber*MAXLOGSRPERPAGE; index++, number++) {
        item = logItem.at(index);
        item->setPos(0, number*85);
        item->show();
        QGraphicsItemAnimation *animation = new QGraphicsItemAnimation(this);
        animation->setItem(item);
        QTimeLine *timeLine = new QTimeLine(400);
        animation->setTimeLine(timeLine);

        if (leftToRight == true) {
            animation->setPosAt(0, QPointF( -608, number*85));
            animation->setPosAt(1, QPointF(0, number*85));
        }
        else {
            animation->setPosAt(0, QPointF( 608, number*85));
            animation->setPosAt(1, QPointF(0, number*85));
        }
        timeLine->start();
    }
}

void LogMessagesItem::hideLogItem()
{
    for (int index = 0; index < logItem.count(); index++) {
        if (logItem.at(index)) {
            logItem.at(index)->hide();
        }
    }
}

void LogMessagesItem::slotCalendarFinish()
{
    showLogs();
}

void LogMessagesItem::slotLogPageChange(int index)
{
    if (currentPageNumber < index) {
        leftToRight = true;
    }
    else {
        leftToRight = false;
    }
    currentPageNumber = index;
    showLogs();
}

/*****************************LogContentItem********************************/
LogContentItem::LogContentItem(QGraphicsItem *parent)
    : QGraphicsItem(parent)
{
    timeText = new QGraphicsTextItem(this);
    timeText->setDefaultTextColor(QColor("#999999"));
    timeText->setFont(QFont("arial", 10, QFont::Normal));
    timeText->setPos(boundingRect().right() - 125, boundingRect().top());

    typeText = new QGraphicsTextItem(this);
    typeText->setDefaultTextColor(QColor("#666666"));
    typeText->setFont(QFont("arial", 10, QFont::Normal));
    typeText->setPos(boundingRect().left() + 15, boundingRect().top() + 10);

    stateText = new QGraphicsTextItem(this);
    stateText->setDefaultTextColor(QColor("#666666"));
    stateText->setFont(QFont("arial", 10, QFont::Normal));
    stateText->setPos(boundingRect().left() + 15, boundingRect().top() + 30);

    describeText = new QGraphicsTextItem(this);
    describeText->setDefaultTextColor(QColor("#666666"));
    describeText->setFont(QFont("arial", 10, QFont::Normal));
    describeText->setPos(boundingRect().left() + 15, boundingRect().top() + 50);
}

LogContentItem::~LogContentItem()
{
}

QRectF LogContentItem::boundingRect() const
{
    return QRectF(0, 0, 608, 80);
}

void LogContentItem::setData(const QList<QString> &data)
{
    timeText->setPlainText(data.at(0));
    typeText->setPlainText(QObject::tr("类型:%1").arg(data.at(1)));
    stateText->setPlainText(QObject::tr("状态:%1").arg(data.at(2)));
    describeText->setPlainText(QObject::tr("描述:%1").arg(data.at(3)));
}

void LogContentItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setPen(QPen(QColor("#BBBBBB")));
    painter->setBrush(QColor("#FFFFFF"));
    painter->drawRect(0, 0, 608, 80);
}
(3)LogMessagesView.h
#ifndef LOGMESSAGESVIEW_H
#define LOGMESSAGESVIEW_H

#include <QGraphicsView>
#include <QTextCodec>
#include <QtGui>
#include <QtCore>
#include <QDebug>

class LogMessagesView : public QGraphicsView
{
    Q_OBJECT

public:
    LogMessagesView(QWidget *parent = 0);
    ~LogMessagesView();

protected:
    void mousePressEvent ( QMouseEvent * event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

private:
    QPoint dragPosition;
    bool bPressFlag;
};

#endif // LOGMESSAGESVIEW_H
(4)LogMessagesView.cpp
#include "LogMessagesView.h"
#include "LogMessagesItem.h"

LogMessagesView::LogMessagesView(QWidget *parent)
    : QGraphicsView(parent)
    , bPressFlag(false)
{
    QTextCodec *codec = QTextCodec::codecForName("System");
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);

    int width = 633;
    int height = 437;
    setWindowFlags(Qt::Widget |Qt::FramelessWindowHint);
    //setStyleSheet("background:transparent;border:0px");

    this->setBackgroundBrush(QBrush(QColor("#EEF7FD")));

    QGraphicsScene *scene = new QGraphicsScene(this);
    scene->setSceneRect(-width/2,-height/2,width,height);
    setSceneRect(2, 2, width - 4, height - 4);
    setScene(scene);
    setCacheMode(QGraphicsView::CacheBackground);
    setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);

    LogMessagesItem *item = new LogMessagesItem;
    this->installEventFilter(item);
    scene->addItem(item);
}

LogMessagesView::~LogMessagesView()
{

}

void LogMessagesView::mousePressEvent ( QMouseEvent * event)
{
    bPressFlag = true;
    dragPosition = event->pos();
    QGraphicsView::mousePressEvent(event);
}

void LogMessagesView::mouseMoveEvent(QMouseEvent *event)
{
    if (bPressFlag) {
        QPoint relaPos(QCursor::pos() - dragPosition);
        move(relaPos);
    }
    QGraphicsView::mouseMoveEvent(event);
}

void LogMessagesView::mouseReleaseEvent(QMouseEvent *event)
{
    bPressFlag = false;
    QGraphicsView::mouseReleaseEvent(event);
}

三、总结

(1)因涉及一些项目内容,此处暂不提供源码,请谅解。读者根据上述思路去完成自己的代码。
(2)可执行程序已上传到CSDN(centos6.6下运行):http://download.csdn.net/detail/taiyang1987912/9436720
(3)若有问题或建议,请留言,在此感谢!

你可能感兴趣的:(linux,qt)