// .h
/* 若窗口是从QDialog继承下来,设置窗口无标题需要加上Qt::Dialog项,否则即使设置了 Qt::FramelessWindowHint,窗口一样有标题,如下:
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
*/
#pragma once
#include <QtWidgets/QWidget>
#include "ui_FaceDetectDemo.h"
class FaceDetectDemo : public QWidget
{
Q_OBJECT
public:
FaceDetectDemo(QWidget *parent = Q_NULLPTR);
~FaceDetectDemo();
void ShowWidget();
void CloseWidget();
private slots:
// 右键菜单
void RightMouseKeyClicked(const QPoint &point);
void ShowWindowMinimize(); // 窗口最小化
private:
void FindWidgetAllChildren();
protected:
void mousePressEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void keyPressEvent(QKeyEvent *);
void closeEvent(QCloseEvent *);
void resizeEvent(QResizeEvent *);
private:
Ui::FaceDetectDemoClass ui;
// 移动窗口
QPoint m_point;
bool m_bPress;
// 保存最开始的大小和字体
struct AutoResize
{
QRect m_rect;
QFont m_font;
};
QRect m_rect;
QFont m_font;
QMap<QWidget*, AutoResize> m_wdgtMapSize; //保存所有窗口最开始大小和字体
};
//.cpp
#include <qlabel.h>
#include <qimage.h>
#include <qstring.h>
#include <qdatetime.h>
#include <QDesktopWidget>
#include <QMouseEvent>
#include <qmenu.h>
#include "FaceDetectDemo.h"
FaceDetectDemo::FaceDetectDemo(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
// 获取屏幕分辨率大小,设置为窗口最初大小
m_rect = this->geometry();
m_font = this->font();
int pointsize = m_font.pointSize();
m_font.setPixelSize(pointsize * 90 / 72); //设置字体大小单位为像素大小,而不是以磅为单位
this->setFont(m_font);
FindWidgetAllChildren();
// 根据桌面分辨率设置窗口大小和字体
QDesktopWidget *widget = QApplication::desktop();
//是不是使用固定分辨率,如果是,则不使用桌面分辨率,因有些系统获取桌面分辨率会失败,比如win8.1,故此时应使用固定分辨率
/*if (Global::IsFixGeometry())
{
widget->setGeometry(QRect(0, 0, Global::GetFixWidth(), Global::GetFixHeight())); //会调用resizeEvent函数重置窗口
}*/
this->setGeometry(widget->geometry()); //会调用resizeEvent函数重置窗口
this->setFont(widget->font());
// 窗口置顶,并且无边框
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
// 右键菜单需要设置
this->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &QWidget::customContextMenuRequested, this, &FaceDetectDemo::RightMouseKeyClicked);
}
FaceDetectDemo::~FaceDetectDemo()
{
CloseWidget();
}
void FaceDetectDemo::ShowWidget()
{
this->show();
}
void FaceDetectDemo::CloseWidget()
{
this->close();
}
void FaceDetectDemo::mousePressEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton)
{
m_bPress = true;
m_point = e->globalPos() - this->pos();
e->accept();
}
}
void FaceDetectDemo::mouseReleaseEvent(QMouseEvent *e)
{
m_bPress = false;
}
void FaceDetectDemo::mouseMoveEvent(QMouseEvent *e)
{
if (m_bPress)
{
move(e->globalPos() - m_point);
e->accept();
}
}
// 按键事件上做响应,因右键菜单的快捷键没反应,故在此响应
void FaceDetectDemo::keyPressEvent(QKeyEvent *e)
{
int videoIndex = 1;
switch (e->key())
{
case Qt::Key_Escape:
this->CloseWidget();
break;
case Qt::Key_M:
ShowWindowMinimize();
break;
}
}
void FaceDetectDemo::closeEvent(QCloseEvent *e)
{
/*QString titlestr = QString::fromLocal8Bit("Prompt dialog");
QString contentstr = QString::fromLocal8Bit("Do you confirm to exit program?");
QMessageBox::StandardButton btn =
QMessageBox::question(this, titlestr, contentstr, QMessageBox::Yes | QMessageBox::No);
if (btn == QMessageBox::Yes)
{
this->CloseWidget();
}
else
{
e->ignore();
}*/
}
// 查找窗口所有的子窗口
void FaceDetectDemo::FindWidgetAllChildren()
{
QList<QWidget*> wls = this->findChildren<QWidget*>();
QList<QWidget*>::iterator it = wls.begin();
int i = 0;
for (; it != wls.end(); it++)
{
AutoResize auresize;
auresize.m_rect = (*it)->geometry();
auresize.m_font = (*it)->font();
m_wdgtMapSize[(*it)] = auresize;
i++;
//WLog(LOG_DEBUG,"i:[%d] [%s]\n", i, (*it)->objectName().toLocal8Bit().data());
}
}
void FaceDetectDemo::resizeEvent(QResizeEvent *e)
{
if (m_rect.width() == 0 || m_rect.height() == 0)
{
QWidget::resizeEvent(e);
return;
}
//取得长宽的缩放比
float scalew = this->width()*1.0 / m_rect.width();
float scaleh = this->height()*1.0 / m_rect.height();
// 取最小的一个
float fontscale = scalew > scaleh ? scaleh : scalew;
// 再在原来大小基础上根据缩放比例调整大小
QMap<QWidget*, AutoResize>::iterator it = m_wdgtMapSize.begin();
for (; it != m_wdgtMapSize.end(); it++)
{
QWidget *item = it.key();
int x = (it.value().m_rect.x())*scalew; // 在最开始的大小的基础上乘以缩放比例
int y = (it.value().m_rect.y())*scaleh;
int w = (it.value().m_rect.width())*scalew;
int h = (it.value().m_rect.height())*scaleh;
item->setGeometry(QRect(x, y, w, h));
QFont font = it.value().m_font;
// 取得最开始的字体大小
int fontsize = font.pixelSize();
if (fontsize <= 0) // 把0也去除,如果为0,会导致界面无法显示
{
fontsize = font.pointSize();
if (fontsize <= 0)
{
qreal sizef = font.pointSizeF();
sizef = sizef > 0 ? sizef : 1;
font.setPointSizeF(sizef* fontscale);
}
else
{
font.setPixelSize(fontsize * fontscale * 90 / 72); // 设置字体大小为像素大小,而不是以磅为单位,
}
}
else
{
font.setPixelSize(fontsize * fontscale);
}
item->setFont(font);
}
QWidget::resizeEvent(e);
}
void FaceDetectDemo::RightMouseKeyClicked(const QPoint &point)
{
QMenu *menu = new QMenu(this);
QAction *minimizeAction = new QAction(QString::fromLocal8Bit("最小化"), menu);
QAction *closeAction = new QAction(QString::fromLocal8Bit("退出"), menu);
// 下面的快捷方式设置了不起作用,另外在按键事件上做了响应
minimizeAction->setShortcut(Qt::Key_M);
closeAction->setShortcut(Qt::Key_Escape);
menu->addAction(minimizeAction);
menu->addAction(closeAction);
connect(minimizeAction, &QAction::triggered, this, &FaceDetectDemo::ShowWindowMinimize);
connect(closeAction, &QAction::triggered, this, &FaceDetectDemo::CloseWidget);
menu->exec(mapToGlobal(point));
//menu->exec(QCursor::pos()); // qtablewidget这些需要使用本语句才获取到正确位置
delete menu;
menu = nullptr;
}
void FaceDetectDemo::ShowWindowMinimize()
{
this->showMinimized(); // 最小化窗口
}