QGraphicsView框架的界面

在view中创建一个item,思路:相当于用qgraphicsItem绘制了一个边框,在自定义的item中添加一个总的QWidget,里面的控件可以通过stylesheet设置透明等等,这样就可以在qt的界面编辑器中进行界面布局,方便,效果如下

具体代码:

DialogItem类的.c文件

#include "MyGraphicsItem.h"
#include <QFontMetrics>
#include <QPainter>
#include <QMouseEvent>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsScene>
#include <QPushButton>
#include <QGraphicsProxyWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGraphicsSceneMouseEvent>


#include <QGraphicsLayout>
#include <QDebug>



TitleBarItem::TitleBarItem(qreal x,qreal y,qreal width,qreal height):
    m_bInPath(false)
{
    m_rect = QRectF(x,y,width,height);
    setAcceptHoverEvents(true);
    setAcceptedMouseButtons(Qt::LeftButton);
}

void TitleBarItem::updateGeometry()
{
    prepareGeometryChange();
    //setPos();
}


void TitleBarItem::setItemTitle(const QString &strText)
{
    m_strtitle = strText;
}

void TitleBarItem::setItemTitleFont(QFont font)
{
    m_font = font;
}

void TitleBarItem::setRect(qreal x, qreal y, qreal width, qreal height)
{
    prepareGeometryChange();
    m_rect = QRectF(x,y,width,height);
    m_closeRect = QRectF(m_rect.right()-50,m_rect.top()+5,40,40);


}

void TitleBarItem::setMainWidget(QWidget *widget)
{
    m_mainWidget = widget;

}

QRectF TitleBarItem::boundingRect() const
{

    return m_rect;
}

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

    Q_UNUSED(option)
    Q_UNUSED(widget)

    m_font.setPointSize(22);
    m_font.setBold(true);
    painter->setFont(m_font);
    QFontMetrics metrics(m_font);
    QRectF rec= metrics.boundingRect(QRect(0,0,150,100), Qt::AlignLeft, m_strtitle);
    m_titleRect = QRectF(m_rect.left()+m_rect.width()/2-rec.width()/2,m_rect.height()/4-rec.height()/6,rec.width(),rec.height());

    //m_rect.width()/2,m_rect.height()/4;
    m_titleRect.translate(5, 5);//移动,调整

    m_closeRect = QRectF(m_rect.right()-50,m_rect.top()+5,40,40);

    QPainterPath path;
    path.moveTo(QPoint(m_rect.left(),m_rect.top()));
    path.lineTo(QPoint(m_rect.left()+m_rect.width(),m_rect.top()));
    path.lineTo(QPoint(m_rect.left()+m_rect.width(),(m_rect.top()+m_rect.height())/2));

    path.lineTo(QPoint(m_titleRect.right()+60,(m_rect.top()+m_rect.height())/2));
    path.lineTo(QPoint(m_titleRect.right()+40,m_rect.top()+m_rect.height()));

    path.lineTo(QPoint(m_titleRect.right()+20,m_rect.top()+m_rect.height()));
    path.lineTo(QPoint(m_titleRect.right()+16,m_rect.top()+m_rect.height()-5));

    path.lineTo(QPoint(m_titleRect.left()-16,m_rect.top()+m_rect.height()-5));
    path.lineTo(QPoint(m_titleRect.left()-20,m_rect.top()+m_rect.height()));

    path.lineTo(QPoint(m_titleRect.left()-40,m_rect.top()+m_rect.height()));
    path.lineTo(QPoint(m_titleRect.left()-60,(m_rect.top()+m_rect.height())/2));

    path.lineTo(QPoint(m_rect.left(),(m_rect.top()+m_rect.height())/2));
    path.lineTo(QPoint(m_rect.left(),m_rect.top()));

    if(m_bInPath)
         painter->setBrush(QColor(85,200,170));
    else
        painter->setBrush(QColor(85,153,170));//QColor(255, 255, 255)   248,222,254

    painter->setPen(Qt::NoPen);

    painter->drawPath(path);
    m_path = path;
    if(m_bInPath)
        painter->setPen(QColor(Qt::green));
    else
        painter->setPen(QColor(Qt::darkGreen));

    painter->drawText(m_titleRect, m_strtitle);
   // painter->drawLine(QPoint(m_titleRect.left()-12,m_rect.height()-2),QPoint(m_titleRect.right()+12,m_rect.height()-2));
    //painter->drawEllipse(m_titleRect.left(),m_rect.height()-2,m_titleRect.width(),2);
    painter->setBrush(QColor(Qt::darkGreen));
    painter->drawRoundRect(m_titleRect.left()-14,m_rect.height()-3,m_titleRect.width()+14*2,2,1);

    painter->drawEllipse(m_closeRect);


}

void TitleBarItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{

    if(m_path.contains(event->pos())){
        m_bMousePressed = true;
    }
    else{
        m_bMousePressed = false;
    }

    if(m_closeRect.contains(event->pos())){
        if(m_mainWidget){
            m_mainWidget->close();
        }

    }

}


void TitleBarItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if(m_path.contains(event->pos())&& m_bMousePressed){
        //移动主窗口
        if(m_mainWidget != NULL){
            m_mainWidget->move(m_mainWidget->pos().x()+event->pos().x()-event->buttonDownPos(Qt::LeftButton).x()\
                               ,m_mainWidget->pos().y()+event->pos().y()-event->buttonDownPos(Qt::LeftButton).y());
        }

    }
    else{
        m_bMousePressed= false;

    }


}

void TitleBarItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    m_bMousePressed = false;
}

void TitleBarItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    if(m_path.contains(event->pos())){
        m_bInPath = true;
    }
    else{
       m_bInPath = false;
    }
    prepareGeometryChange();
}

void TitleBarItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{

     if(m_path.contains(event->pos())){
         m_bInPath = true;
     }
     else{
        m_bInPath = false;
     }
     prepareGeometryChange();

}

void TitleBarItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    if(m_path.contains(event->pos())){
        m_bInPath = true;

    }
    else{
       m_bInPath = false;
    }
    prepareGeometryChange();
}

void TitleBarItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
    if(m_path.contains(event->pos())){

        if(m_mainWidget != NULL){
            if(m_mainWidget->isMaximized()){
                m_mainWidget->showNormal();
            }
            else{
               m_mainWidget->showMaximized(); //m_mainWidget->showFullScreen();
            }

        }
    }
    else{
        m_bInPath = false;
    }
   //
    //prepareGeometryChange();

}





DialogItem::DialogItem(qreal x, qreal y, qreal width, qreal height)
    :m_bInPath(false)
    ,m_bIsPressed(false)
{
    m_rect = QRectF(x,y,width,height);
    //setTransformOriginPoint(100,100);

//    m_btnOK = new QPushButton("确定");
//    m_btnOK->setStyleSheet("    font-size: 16px;\
//                                color: #BDC8E2;\
//                                height: 30px;   \
//                                width:  60px;   \
//                                border-radius: 4px;\
//                                background-color: #2E3648;");
//    m_btnCancel = new QPushButton("取消");
//    m_btnCancel->setStyleSheet("    font-size: 16px;\
//                                color: #BDC8E2;\
//                                height: 30px;   \
//                                width:  60px;   \
//                                border-radius: 4px;\
//                                background-color: #2E3648;");

//    m_graphWidget = new QWidget();
//    m_graphWidget->setObjectName("mainWidget");
//    m_graphWidget->setStyleSheet("QWidget#mainWidget{border-radius: 5px;\
//                                 border:2px solid gray;\
//                                 background-color: transparent}");//
//    QVBoxLayout* vLayout = new QVBoxLayout();
//    QHBoxLayout* hLayout = new QHBoxLayout();
//    hLayout->addWidget(m_btnOK);
//    hLayout->addWidget(m_btnCancel);

//    vLayout->addStretch(6);
//    vLayout->addLayout(hLayout,1);
//    //vLayout->setMargin(0);
//    vLayout->setContentsMargins(5,5,5,5);

//    m_graphWidget->setLayout(vLayout);



    m_timeline = new QTimeLine(1000);
    m_timeline->setFrameRange(0, 100);
    m_timeline->setLoopCount(1);
    m_timeline->setCurveShape(QTimeLine::EaseInOutCurve);    //frameChanged()发出的值像sin曲线一样,1,2,...,99,100,99,...,2,1
    m_timeline->setUpdateInterval(25);    //更新频率(也就是frameChanged(int)的执行速度),每25ms更新一次,相当于每秒40帧,

    m_animation = new QGraphicsItemAnimation;
    m_animation->setItem(this);
    m_animation->setTimeLine(m_timeline);

    //旋转的定时器
    m_timeline1 = new QTimeLine(500);
    m_timeline1->setFrameRange(0, 100);
    m_timeline1->setLoopCount(1);
    m_timeline1->setCurveShape(QTimeLine::EaseInOutCurve);    //frameChanged()发出的值像sin曲线一样,1,2,...,99,100,99,...,2,1
    m_timeline1->setUpdateInterval(25);

    connect(m_timeline1, SIGNAL(frameChanged(int)), this, SLOT(scaleAnimation(int)));
    m_rotate_type = Qt::ZAxis;
    //刚开始播放缩放动画
    m_timeline1->start();



}

void DialogItem::updateGeometry()
{

}

void DialogItem::setItemTitle(const QString &strText)
{
    m_strtitle = strText;
}

void DialogItem::setItemTitleFont(QFont font)
{

}

void DialogItem::setRect(qreal x, qreal y, qreal width, qreal height)
{
    m_rect = QRectF(x,y,width,height);
    m_closeButtonRect = QRectF(m_rect.right()-35,m_rect.top()+10,35,35);


    prepareGeometryChange();

}

void DialogItem::setDialogWidget(QWidget *widget)
{
    if(scene())
        m_pScene = scene();
    m_graphWidget = widget;
    m_widget = m_pScene->addWidget(m_graphWidget);

    m_widget->setParentItem(this);

}

void DialogItem::setRotateType(Qt::Axis type)
{
    m_rotate_type = type;
    //开始动画
     m_timeline1->start();
}

void DialogItem::xuanzhuan()
{
    m_animation->clear();
    m_animation->setRotationAt(1,360);
    m_timeline->start();

}

void DialogItem::pingyi()
{
    m_animation->clear();
    m_animation->setTranslationAt(0.25, 200, 0);
    m_animation->setTranslationAt(0.5, 0, 0);
    m_animation->setTranslationAt(0.75, -200, 0);
    m_animation->setTranslationAt(1.0, 0, 0);
    m_timeline->start();
}

void DialogItem::fanzhuan(int flag)
{

}

void DialogItem::suofang()
{
    m_animation->clear();
    m_animation->setScaleAt(1,0,0);
    m_timeline->start();
}

void DialogItem::cuoqie()
{
    m_animation->clear();
    m_animation->setShearAt(0.25,0.2,0);
    m_animation->setShearAt(0.5,0,0);
    m_animation->setShearAt(0.75,-0.2,0);
    m_animation->setShearAt(1,0,0);
    m_timeline->start();

}

QRectF DialogItem::boundingRect() const
{
    return m_rect;
}

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

    m_font.setPointSize(15);
    m_font.setBold(true);
    painter->setFont(m_font);
    QFontMetrics metrics(m_font);
    QRectF rec= metrics.boundingRect(QRect(0,0,150,100), Qt::AlignLeft, m_strtitle);
    m_titleRect = QRectF(m_rect.left()+m_rect.width()/2-rec.width()/2,m_rect.top()+rec.height()/4,rec.width(),rec.height());

    //m_rect.width()/2,m_rect.height()/4;
    m_titleRect.translate(5, 5);//移动,调整
    if(m_graphWidget)
        m_graphWidget->resize(m_rect.width()-30,m_rect.height()-m_titleRect.height()-30);
    m_widget->setPos(m_rect.left()+15,m_titleRect.top()+m_titleRect.height()+10);

    QPainterPath path;
    /*
    */
    path.moveTo(QPoint(m_rect.left()+15,m_titleRect.bottom()));
    path.lineTo(QPoint(m_titleRect.left()-20,m_titleRect.bottom()));
    path.lineTo(QPoint(m_titleRect.left()-10,m_titleRect.top()));
    path.lineTo(QPoint(m_titleRect.right()+10,m_titleRect.top()));
    path.lineTo(QPoint(m_titleRect.right()+20,m_titleRect.bottom()));
    path.lineTo(QPoint(m_rect.right()-15,m_titleRect.bottom()));
    path.lineTo(QPoint(m_rect.right(),m_titleRect.bottom()+15));
    path.lineTo(QPoint(m_rect.right(),m_rect.bottom()-15));
    path.lineTo(QPoint(m_rect.right()-15,m_rect.bottom()));
    path.lineTo(QPoint(m_rect.left()+15,m_rect.bottom()));
    path.lineTo(QPoint(m_rect.left(),m_rect.bottom()-15));
    path.lineTo(QPoint(m_rect.left(),m_titleRect.bottom()+15));
    path.lineTo(QPoint(m_rect.left()+15,m_titleRect.bottom()));


    painter->setPen(QColor(Qt::gray));
    QLinearGradient backgroundGradient(0.5, 0.0, 0.5, 1.0);
    backgroundGradient.setColorAt(0.0,QColor(78,228,228,100) );//QRgb(0x4EE4E4)
    backgroundGradient.setColorAt(1.0,QColor(58,96,249,100) );//QRgb(0x3A60F9)
    backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode);
    painter->setBrush(backgroundGradient);

    painter->drawPath(path);

    if(m_bIsPressed)
        painter->setPen(QColor(Qt::yellow));
    else
        painter->setPen(QColor(Qt::darkYellow));

    painter->drawText(m_titleRect, m_strtitle);

    painter->drawEllipse(m_closeButtonRect);



}

void DialogItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    //判断
    if(m_titleRect.contains(event->pos())){
        m_bIsPressed = true;
        prepareGeometryChange();

    }
    if(m_closeButtonRect.contains(event->pos())){
        //关闭按钮被点击
        //qDebug()<<"关闭按钮被点击";
        //suofang();
        //hide();
        //反向动画
        m_timeline1->setDirection(QTimeLine::Backward);
        m_timeline1->start();
    }

}

void DialogItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if(m_bIsPressed){
        //qDebug()<<__FUNCTION__<<event->lastPos()<<event->pos();
        this->moveBy(event->pos().x()-event->lastPos().x(),event->pos().y()-event->lastPos().y());
    }


}

void DialogItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    m_bIsPressed = false;
    prepareGeometryChange();

}

void DialogItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{

}

void DialogItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    if(m_titleRect.contains(event->pos())){

    }
    else{


    }
}

void DialogItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{

}


//缩放槽函数
void DialogItem::scaleAnimation(int frame)
{

     QPointF pt = this->boundingRect().center();
     qreal scaleX_Y = (frame) / 100.0;
     QTransform tran;
     tran.translate(pt.x(), pt.y());
     tran.scale(scaleX_Y, scaleX_Y);

     tran.rotate(frame*3.6,m_rotate_type);
     //tran.shear(0.25,0);
     this->setTransform(tran);
     QTransform t;
     t.translate(-pt.x(), -pt.y());
     this->setTransform(t, true);
}

DialogItem类的 .h文件

#ifndef MYGRAPHICSITEM_H
#define MYGRAPHICSITEM_H

#include <QGraphicsItem>
#include <QPushButton>
#include <QGraphicsWidget>
#include <QWidget>
#include <QFont>
#include <QTimeLine>
#include <QGraphicsItemAnimation>
#include <QObject>

QT_BEGIN_NAMESPACE
class QGraphicsSceneMouseEvent;
QT_END_NAMESPACE


class TitleBarItem :public QObject,public QGraphicsItem
{
    Q_OBJECT
public:
    TitleBarItem(qreal x, qreal y, qreal width, qreal height);//QGraphicsItem *parent
    void updateGeometry();
    void setItemTitle(const QString &strText);
    void setItemTitleFont(QFont font);
    void setRect(qreal x, qreal y, qreal width, qreal height);
    void setMainWidget(QWidget* widget);

protected:
    QRectF boundingRect() const override;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) override;
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
    void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;

private:
    QRectF m_rect;      //整个区域的rect
    QRectF m_titleRect; //标题的绘制rect
    QRectF m_closeRect; //关闭按钮的rect

    QString m_strtitle;
    QFont   m_font;

    QPainterPath m_path;

    bool m_bInPath;
    bool m_bMousePressed;

    QWidget* m_mainWidget;


};


class DialogItem : public QObject,public QGraphicsItem{

    Q_OBJECT
public:
    DialogItem(qreal x,qreal y,qreal width,qreal height);
    void updateGeometry();
    void setItemTitle(const QString &strText);
    void setItemTitleFont(QFont font);
    void setRect(qreal x, qreal y, qreal width, qreal height);
    //scene中additem调用后,再调用下面的函数(可以通过传一个QWidget的参数,实现通用)
    void setDialogWidget(QWidget* widget);

    void setRotateType(Qt::Axis type);
    //
    void xuanzhuan();
    void pingyi();
    void fanzhuan(int flag);
    void suofang();
    void cuoqie();//错切


protected:
    QRectF boundingRect() const override;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) override;
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
    void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;

private slots:
    void scaleAnimation(int  frame);

private:
    QRectF m_rect;              //整个区域的rect
    QRectF m_titleRect;         //标题的绘制rect
    QRectF  m_closeButtonRect;  //关闭按钮的rect

    QString m_strtitle;
    QFont   m_font;

    QPainterPath m_path;

    bool m_bInPath;
    bool m_bIsPressed;

    QGraphicsScene * m_pScene;
    QPushButton*  m_btnOK;
    QPushButton*  m_btnCancel;
    QGraphicsProxyWidget* m_widget;
    QWidget * m_graphWidget;

    QGraphicsItemAnimation* m_animation;
    QTimeLine   * m_timeline;
    QTimeLine   * m_timeline1;

    Qt::Axis m_rotate_type;


};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gws09876

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值