在qt界面上内嵌拥有独立句柄的窗口

背景

在qt程序中,如果数据刷新频率过高,容易造成窗口卡顿,因为qt程序是整个窗口刷新,在此种背景下可以在qt程序的主程序上内嵌一个拥有独立句柄的窗口,两个窗口刷新就互不干扰。

案例

以下例子,在主窗口中内嵌一个窗口,窗口显示是QChart相关的图标。

#pragma once

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include  
#include 
#include 
#include 
#include 
#include 

namespace ViewDataChart
{
	QT_CHARTS_USE_NAMESPACE

	class DataLineView : public QWidget
	{
		Q_OBJECT
	public:
		DataLineView(int minY, int maxY, int numY, int maxX, int numX);
		~DataLineView();

		// 显示设置
		void SetYNum(int value);
		void SetYMax(int value);
		void SetYMin(int value);
		void SetXNum(int value);
		void SetXMax(int value);

	public slots:
		void UpdateLine();
		// 赋值
		void AppendValue(unsigned short value);
		void AppendValue(std::vector<unsigned short>& list);

	protected:
		void resizeEvent(QResizeEvent*);

	private:
		QVBoxLayout* verticalLayout;
		QGraphicsView* pGrapView_;
		QChartView* pView_;
		QWidget* m_winContainer;

		QChart* pWavePic_;
		QValueAxis* pAxisX_;
		QValueAxis* pAxisY_;
		QLineSeries* pLineData_;

	//	QTimer* pTimer_;
		int objNum_;
		int maxXNum_;
		std::mutex mtxData_;
		std::vector<ushort> values_;
	};
};

#include "DataLineView.h"
#include 

ViewDataChart::DataLineView::DataLineView(int minY, int maxY, int numY, int maxX, int numX)
	: maxXNum_(maxX)
{
	if (this->objectName().isEmpty())
		this->setObjectName(QStringLiteral("PlayVideoWidget"));
	this->resize(1, 1);
	verticalLayout = new QVBoxLayout(this);
	verticalLayout->setSpacing(0);
	verticalLayout->setContentsMargins(0, 0, 0, 0);
	verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
	verticalLayout->setContentsMargins(0, 0, 0, 0);
	//this->setWindowTitle("");
	QMetaObject::connectSlotsByName(this);

	// wave
	pAxisX_ = new QValueAxis();
	pAxisY_ = new QValueAxis();
	pAxisX_->setMin(0);
	pAxisX_->setMax(maxX);
	//	pAxisX_->setVisible(false);
	pAxisY_->setMin(minY);
	pAxisY_->setMax(maxY);
	pAxisY_->setTickCount(numY + 1);
	pAxisX_->setTickCount(numX + 1);

	pLineData_ = new QLineSeries();
	pLineData_->setPointsVisible(true);
	pLineData_->setUseOpenGL(true);
	//  //pLineData_->setName("");

	pWavePic_ = new QChart();
	pWavePic_->addAxis(pAxisY_, Qt::AlignLeft);
	pWavePic_->addAxis(pAxisX_, Qt::AlignBottom);
	pWavePic_->addSeries(pLineData_);
	pWavePic_->setAnimationOptions(QChart::SeriesAnimations);
	pLineData_->attachAxis(pAxisX_);
	pLineData_->attachAxis(pAxisY_);

	pView_ = new QChartView(pWavePic_);
	pView_->setVisible(true);
	pView_->resize(geometry().size());
	pView_->setChart(pWavePic_);
	pView_->setRenderHint(QPainter::Antialiasing);

	pView_->setStyleSheet("background-color: rgb(255, 255, 255);");

	// 此处开始创建独立句柄
	QWindow* win = pView_->windowHandle();
	if (!win)
		win = pView_->topLevelWidget()->windowHandle();
	win->setFlags(Qt::FramelessWindowHint);
	QWindowsWindowFunctions::setHasBorderInFullScreen(win, true);
	m_winContainer = QWidget::createWindowContainer(win, this);
	m_winContainer->setStyleSheet(QString::fromUtf8("border:0px"));
	m_winContainer->setStyleSheet("background-color: rgb(255, 255, 255);");
	m_winContainer->resize(geometry().size());

	verticalLayout->addWidget(m_winContainer);

	/*pTimer_ = new QTimer(this);
	pTimer_->setSingleShot(false);
	pTimer_->setInterval(5);
	connect(pTimer_, &QTimer::timeout, this, &ViewDataChart::DataLineView::UpdateLine);
	pTimer_->start();*/

	//setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
	/*QPalette palette = this->palette();
	palette.setColor(QPalette::Base, Qt::transparent);
	setPalette(palette);
	setAttribute(Qt::WA_TranslucentBackground);
	setWindowFlags(Qt::FramelessWindowHint);*/
}

ViewDataChart::DataLineView::~DataLineView()
{
	delete pLineData_;
	pLineData_ = nullptr;

	delete pAxisX_;
	pAxisX_ = nullptr;
	delete pAxisY_;
	pAxisY_ = nullptr;

	delete pWavePic_;
	pWavePic_ = nullptr;

	delete pView_;
	pView_ = nullptr;

	delete verticalLayout;
	verticalLayout = nullptr;
}

// 设置y轴刻度数
void ViewDataChart::DataLineView::SetYNum(int value)
{
	pAxisY_->setTickCount(value);
}

// 设置y轴最大值
void ViewDataChart::DataLineView::SetYMax(int value)
{
	pAxisY_->setMax(value);
}

// 设置y轴最小值
void ViewDataChart::DataLineView::SetYMin(int value)
{
	pAxisY_->setMin(value);
}

// 设置x轴刻度数
void ViewDataChart::DataLineView::SetXNum(int value)
{
	pAxisX_->setTickCount(value);
}

// 设置x轴最大值
void ViewDataChart::DataLineView::SetXMax(int value)
{
	for (int i = 0; i < value - maxXNum_; ++i)
	{
		if (pLineData_->count() > 0)
			pLineData_->remove(0);
	}

	maxXNum_ = value;
	pAxisX_->setMax(maxXNum_);
}

// 添加数据值
void ViewDataChart::DataLineView::AppendValue(unsigned short value)
{
	std::unique_lock<std::mutex> lock(mtxData_);

	while (pLineData_->count() + 1 > maxXNum_ && maxXNum_ > 1)
	{
		pLineData_->remove(0);
	}
	pLineData_->append(pLineData_->count() + 1, value);
}


// 添加数据值(数组)
void ViewDataChart::DataLineView::AppendValue(std::vector<unsigned short>& list)
{
	std::unique_lock<std::mutex> lock(mtxData_);
	values_ = list;
	pLineData_->clear();
	for (int i = 0; i < list.size(); ++i)
	{
		pLineData_->append(QPointF(i, list[i]));
	}
}

void ViewDataChart::DataLineView::resizeEvent(QResizeEvent* event)
{
	if (pView_)
	{
		pView_->show();
		pView_->resize(geometry().size());
		pView_->setVisible(true);
		//pView_->resize(geometry().size());
	}
	QWidget::resizeEvent(event);
}

// 更新图像
void ViewDataChart::DataLineView::UpdateLine()
{

}

案例中数据显示未做完善,在构造函数注明创建独立句柄的代码处。
如下图是效果图,外表看无法看出是内嵌窗口,可以使用 QWidget::winId 函数来获取窗口句柄(HWND)。
在qt界面上内嵌拥有独立句柄的窗口_第1张图片

你可能感兴趣的:(qt,开发语言)