QT QGraphicsView QGraphicsWidget中改变窗口大小会导致部分控件丢失
之前搜寻各方帖子,看到说QGraphicsWidget与QWidget在部分功能上存在一些不同,例如窗口旋转缩放等情况下,于是我采用QGraphicsWidget作为基础窗口,并再次基础上进行绘图操作.但在实际操作中发现,当我用鼠标改变整体窗口时,继承自QGraphicsWidget部件会有一定几率不显示,并且没有调用该部件的paint事件?各处查找,没有找到相关原因,在此向各位求教.
以下为码源:
以下为码源:
//main.cpp
#include <QtWidgets/QApplication>
#include "lineWidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
lineWidget* w = new lineWidget();
w->resize(800,450);
w->show();
return app.exec();
} //lineWidget.h
#ifndef lineWidget_h
#define lineWidget_h
#include <QWidget>
#include "GraphicsView.h"
class lineWidget: public QWidget
{
Q_OBJECT
Q_DISABLE_COPY(timeLine)
public:
explicit lineWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~lineWidget(){}
//>获取单例
static lineWidget* GetInstance() { return m_pInstance; }
//>获取指针
GraphicsView* GetlineWidgetView() { return m_plineWidgetView; }
private:
static lineWidget* m_pInstance;
GraphicsView* m_plineWidgetView;
};
#endif // lineWidget_h//lineWidget.cpp
#include "lineWidget.h"
#include <QHBoxLayout>
lineWidget* lineWidget::m_pInstance = nullptr;
lineWidget::lineWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent,f)
{
Q_ASSERT(m_pInstance == nullptr);
m_pInstance = this;
m_plineWidgetView= new GraphicsView(this);
QHBoxLayout* hLay = new QHBoxLayout(this);
hLay->addWidget(m_plineWidgetView);
setLayout(hLay);
}//GraphicsView.h
#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H
#include <QGraphicsView>
#include "GraphicsScene.h"
class GraphicsView : public QGraphicsView
{
Q_OBJECT
public:
explicit GraphicsView(QWidget *parent = 0);
void setscene(GraphicsScene* pCurScene);
GraphicsScene* getscene();
virtual ~GraphicsView(){}
protected:
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *pEvent) override;
private:
//>加载场景
GraphicsScene *m_pCurScene;
};
#endif // GRAPHICSVIEW_H//GraphicsView.cpp
#include "GraphicsView.h"
GraphicsView::GraphicsView(QWidget *parent)
: QGraphicsView(parent)
{
setWindowFlags(Qt::FramelessWindowHint);
setBackgroundBrush(QColor(62, 62, 66));
QRect r(-width()/2, -height()/2, width(), height());
m_pCurScene = new GraphicsScene(r,this);
setscene(m_pCurScene);
}
void GraphicsView::setscene(GraphicsScene* pCurScene)
{
m_pCurScene = pCurScene;
setScene(pCurScene);
}
GraphicsScene* GraphicsView::getscene()
{
return m_pCurScene;
}
void GraphicsView::mousePressEvent(QMouseEvent *event)
{
return QGraphicsView::mousePressEvent(event);
}
void GraphicsView::mouseMoveEvent(QMouseEvent *pEvent)
{
return QGraphicsView::mouseMoveEvent(pEvent);
}//GraphicsScene.h
#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include <QGraphicsScene>
class timeWidget;
class GraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit GraphicsScene(const QRectF &sceneRect, QObject *parent = 0);
virtual ~GraphicsScene(){}
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *pEvent) override;
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent) override;
private:
timeWidget *m_timeWidget;
};
#endif // GRAPHICSVIEW_HGraphicsScene.cpp
#include "GraphicsScene.h"
#include "timeWidget.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
GraphicsScene::GraphicsScene(const QRectF &sceneRect, QObject *parent)
: QGraphicsScene(sceneRect,parent)
{
m_timeWidget = new timeWidget();
addItem(m_timeWidget);
}
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
{
return QGraphicsScene::mousePressEvent(pEvent);
}
void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *pEvent)
{
return QGraphicsScene::mouseMoveEvent(pEvent);
}
//timeWidget.h
#ifndef TIMEWIDGET_H
#define TIMEWIDGET_H
#include <QGraphicsWidget>
class Stripe;
class QGraphicsLinearLayout;
class timeWidget : public QGraphicsWidget
{
Q_OBJECT
public:
explicit timeWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
virtual ~timeWidget(){}
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
public slots:
void addStripe(Stripe* stripe = 0);
private:
void CreateLayout();
private:
QGraphicsLinearLayout *m_pLayout;
//> 窗口集合
QList<Stripe*> m_stripies;
};
#endif // TIMEWIDGET_H//timeWidget.cpp
#include "timeWidget.h"
#include "rulerwidget.h"
#include "CursorItem.h"
#include "Stripe.h"
#include <QGraphicsLinearLayout>
#include <QWidget>
//#include <QGraphicsScene>
timeWidget::timeWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
: QGraphicsWidget(parent,wFlags)
{
CreateLayout();
for( int i = 0 ; i < 5 ; i++)
addStripe();
}
void timeWidget::CreateLayout()
{
m_pLayout = new QGraphicsLinearLayout(Qt::Vertical,this);
m_pLayout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
m_pLayout->setContentsMargins(0, 0, 0, 0);
m_pLayout->setSpacing(0);
m_pLayout->setPreferredWidth(0);
setLayout(m_pLayout);
}
void timeWidget::addStripe(Stripe* parent)
{
Stripe *new_stripe;
if( parent )
new_stripe = new Stripe(parent);
else
new_stripe = new Stripe(this);
new_stripe->setZValue(-10);
new_stripe->setBackColor(QColor(37,37,38));
m_pLayout->addItem(new_stripe);
m_stripies << new_stripe;
}
void timeWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QRect rc( widget->rect() );
int stripieHeight(0);
int i(0);
for ( auto stripie : m_stripies )
{
stripie->setOriginHeight( stripieHeight );
stripieHeight += stripie->getHeightPercentage() * rc.height()/2;
i++;
}
}//Stripe.h
#ifndef TRACK_H
#define TRACK_H
#include "rectWidgetBase.h"
class Stripe : public rectWidgetBase
{
Q_OBJECT
public:
explicit Stripe(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
explicit Stripe(Stripe *parent, Qt::WindowFlags wFlags = 0);
virtual ~Stripe(){}
protected:
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
private:
//>是否为子项
bool m_isChildren;
};
#endif // CURSORITEM_H//Stripe.cpp
#include "Stripe.h"
#include <QPainter>
Stripe::Stripe(QGraphicsItem *parent,Qt::WindowFlags wFlags)
: rectWidgetBase(parent,wFlags)
, m_isChildren(false)
{
}
Stripe::Stripe(Stripe *parent, Qt::WindowFlags wFlags)
: rectWidgetBase(parent,wFlags)
, m_isChildren(true)
{
}
void Stripe::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
rectWidgetBase::paint(painter,option,widget);
// 绘制顶部边框线
painter->setPen(QColor(0,0,0));
painter->drawLine( rect().topLeft(), rect().topRight() );
}
//rectWidgetBase.h
#ifndef RECTWIDGETBASE_H
#define RECTWIDGETBASE_H
#include <QGraphicsWidget>
class rectWidgetBase : public QGraphicsWidget
{
Q_OBJECT
public:
explicit rectWidgetBase(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
virtual ~rectWidgetBase(){}
//>设置起始高度
inline void setOriginHeight(int originheight){m_originheight = originheight;}
//>设置高度占窗口百分比
inline void setHeightPercentage(double heightPercentage){m_heightPercentage = heightPercentage;}
//>设置宽度占窗口百分比
inline void setWidthPercentage(double widthPercentage){m_widthPercentage = widthPercentage;}
//>设置背景色
inline void setBackColor(QColor color){m_backcolor = color;}
//>获取左上角X坐标
inline int getWidgetLeftTopX(){ return m_leftTopX; }
//>获取左上角Y坐标
inline int getWidgetLeftTopY(){ return m_leftTopY; }
//>获取宽度
inline int getWidgetWidth(){ return m_width; }
//>获取宽度百分比
inline double getWidthPercentage(){ return m_widthPercentage; }
//>获取高度
inline int getWidgetHeight(){ return m_height; }
//>获取条形框高度百分比
inline double getHeightPercentage(){ return m_heightPercentage; }
protected:
//>重绘
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) override;
private:
//>高度占窗口百分比
double m_heightPercentage;
//>初始高度
int m_originheight;
//>高度
int m_height;
//>宽度占窗口百分比
double m_widthPercentage;
//>宽度
int m_width;
//>背景色
QColor m_backcolor;
//>左上角顶点X坐标
int m_leftTopX;
//>左上角顶点Y坐标
int m_leftTopY;
};
#endif // RECTWIDGETBASE_H
//rectWidgetBase.cpp
#include "rectWidgetBase.h"
#include <QWidget>
#include <QPainter>
#include <QGraphicsScene>
rectWidgetBase::rectWidgetBase(QGraphicsItem *parent,Qt::WindowFlags wFlags)
: QGraphicsWidget(parent,wFlags)
, m_leftTopX(0)
, m_leftTopY(0)
, m_width(0)
, m_height(0)
, m_originheight(0)
, m_widthPercentage(0.4)
, m_heightPercentage(0.2)
, m_backcolor(QColor(45,45,48))
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
setContentsMargins(0, 0, 0, 0);
setFlags(QGraphicsItem::ItemSendsScenePositionChanges);
}
void rectWidgetBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QRect rc( widget->rect() );
double left = rc.width() / 2 * m_widthPercentage;
m_leftTopX = -rc.width() / 2 + left;
m_leftTopY = -rc.height() / 2 + m_originheight;
m_width = rc.width() - left - 1;
m_height = rc.height() / 2 * m_heightPercentage;
//> 绘制条形框背景
painter->setBrush(m_backcolor);
painter->setPen(Qt::NoPen/*QColor(0, 255, 0)*/);
QRect r(m_leftTopX, m_leftTopY, m_width, m_height);
resize(m_width, m_height);
painter->drawRect( rect() );
setPos(m_leftTopX, m_leftTopY);
if ( scene() )
scene()->update();
}
...全文
相关推荐
QT中QGraphicsView窗口滑动
我们可以通过设置QGraphicsView的视口大小来定义窗口的显示范围,并通过setScene函数将QGraphicsScene添加到QGraphicsView中。
QT:一个简洁美观的自定义温度控件
QSS类似于HTML中的CSS,允许开发者使用类似CSS的语法来改变QT控件的外观,包括颜色、字体、边框、背景等。这使得控件可以轻松地适应不同主题或设计要求。
Qt汽车仪表界面
QGraphicsView是一个窗口,用于显示QGraphicsScene中的对象,而QGraphicsScene则是一个二维图形场景,可以包含各种图形元素。
QT 子窗体透明源码
在QT中实现子窗体透明,主要是通过QGraphicsView和QGraphicsWidget等类提供的图形场景功能来完成。
Qt 按钮收缩,点击show按钮,在按钮后面缓缓展开三个按钮,再次点击show按钮,后面的三个按钮缓缓缩回
这两个类是Qt图形视图框架的一部分,它们可以用来显示复杂的2D图形和动画。你可以创建一个QGraphicsView,并在其内部设置一个QGraphicsScene。


