521 lines
17 KiB
C++
521 lines
17 KiB
C++
|
||
#ifndef QSS_H
|
||
#define QSS_H
|
||
|
||
#include <QWidget>
|
||
#include <QMainWindow>
|
||
#include <QDialog>
|
||
#include <QMessageBox>
|
||
#include <QFrame>
|
||
#include <QDockWidget>
|
||
#include <QPushButton>
|
||
#include <QAbstractNativeEventFilter>
|
||
#include <QDebug>
|
||
#include <QThread>
|
||
|
||
#include "ui_qsstoast.h"
|
||
#include "ui_process.h"
|
||
|
||
#ifdef __MINGW32__
|
||
#include "windows.h"
|
||
#include "winuser.h"
|
||
#pragma comment(lib, "libuser32.a")
|
||
#endif
|
||
|
||
class QPushButton;
|
||
class QLabel;
|
||
class QMouseEvent;
|
||
#define STANDARD_DPI 96.0
|
||
#define WM_DPICHANGED 0x02e0
|
||
|
||
|
||
typedef enum{
|
||
RA_Resize = 1,
|
||
RA_FixedWidth = 2,
|
||
RA_FixedHeight = 4,
|
||
RA_FixedSize = 8,
|
||
RA_MinimumSize = 16,
|
||
RA_MinimumHeight = 32,
|
||
RA_MinimumWidth = 64,
|
||
RA_MaximumSize = 128,
|
||
RA_MaximumHeight = 256,
|
||
RA_MaximumWidth = 512
|
||
}ReiszeActions ;
|
||
|
||
|
||
|
||
|
||
#define DECLARE_RESIZE() \
|
||
void resize(int w, int h);void resize(const QSize &); void setFixedHeight(int w); \
|
||
void setFixedWidth(int w);void setFixedSize(int w, int h);void setFixedSize(const QSize &s); \
|
||
void setMinimumSize(const QSize &);void setMinimumSize(int minw, int minh); \
|
||
void setMinimumHeight(int minh);void setMinimumWidth(int minw); \
|
||
void setMaximumSize(const QSize &);void setMaximumSize(int maxw, int maxh); \
|
||
void setMaximumHeight(int minh);void setMaximumWidth(int minw);
|
||
|
||
// 用宏强制覆盖的方法不使用了,因为QSSMainWindow本身已经在event事件内做处理,每个event都重写了,无需再去覆盖。
|
||
#define DEFINE_RESIZE(name)\
|
||
void Qss##name::resize(int w, int h){ m_sizeActions |= RA_Resize; float scale = cale; m_size = QSize(w, h);Q##name::resize(m_size.width() * scale, m_size.height() * scale);}\
|
||
void Qss##name::resize(const QSize & size){ m_sizeActions |= RA_Resize; float scale = cale;m_size = size;Q##name::resize(m_size * scale);}\
|
||
void Qss##name::setFixedHeight(int h){m_sizeActions |= RA_FixedHeight;float scale = cale;m_size.setHeight(h);Q##name::setFixedHeight(m_size.height() * scale);}\
|
||
void Qss##name::setFixedWidth(int w){m_sizeActions |= RA_FixedWidth;float scale = cale;m_size.setWidth(w);Q##name::setFixedWidth(m_size.width() * scale);}\
|
||
void Qss##name::setFixedSize(int w, int h){m_sizeActions |= RA_FixedSize;float scale = cale; m_size = QSize(w, h); this->m_frame->setFixedSize(m_size.width() * scale, m_size.height() * scale) ; }\
|
||
void Qss##name::setFixedSize(const QSize & size){m_sizeActions |= RA_FixedSize;float scale = cale; m_size = size; Q##name::setFixedSize(m_size * scale);}\
|
||
void Qss##name::setMinimumSize(const QSize & size){m_sizeActions |= RA_MinimumSize;float scale = cale;m_minimumSize = size; Q##name::setMinimumSize(m_minimumSize * scale);}\
|
||
void Qss##name::setMinimumSize(int w, int h){m_sizeActions |= RA_MinimumSize;float scale = cale; m_minimumSize = QSize(w, h); Q##name::setMinimumSize(m_minimumSize.width() * scale, m_minimumSize.height() * scale);}\
|
||
void Qss##name::setMinimumHeight(int h){m_sizeActions |= RA_MinimumHeight;float scale = cale;m_minimumSize.setHeight(h); Q##name::setMinimumHeight(m_minimumSize.height() * scale);}\
|
||
void Qss##name::setMinimumWidth(int w){m_sizeActions |= RA_MinimumWidth;float scale = cale; m_minimumSize.setWidth(w); Q##name::setMinimumWidth(m_minimumSize.width() * scale);}\
|
||
void Qss##name::setMaximumSize(const QSize & size){m_sizeActions |= RA_MaximumSize;float scale = cale; m_maximumSize = size; Q##name::setMaximumSize(m_maximumSize * scale);}\
|
||
void Qss##name::setMaximumSize(int w, int h){m_sizeActions |= RA_MaximumSize;float scale = cale; m_maximumSize = QSize(w, h); Q##name::setMaximumSize(m_maximumSize.width() * scale, m_maximumSize.height() * scale);}\
|
||
void Qss##name::setMaximumHeight(int h){m_sizeActions |= RA_MaximumHeight;float scale = cale; m_maximumSize.setHeight(h); Q##name::setMaximumHeight(m_maximumSize.height() * scale);}\
|
||
void Qss##name::setMaximumWidth(int w){m_sizeActions |= RA_MaximumWidth;float scale = cale; m_maximumSize.setWidth(w); Q##name::setMaximumWidth(m_maximumSize.width() * scale);}
|
||
|
||
#define DEFINTE_SCALE_RESIZE(name)\
|
||
if (m_sizeActions.testFlag(RA_FixedWidth)){Qss##name::setFixedWidth(m_size.width() * scale);}\
|
||
if (m_sizeActions.testFlag(RA_FixedHeight)){Qss##name::setFixedHeight(m_size.height() * scale);}\
|
||
if (m_sizeActions.testFlag(RA_FixedSize)){Qss##name::setFixedSize(m_size * scale);}\
|
||
if (m_sizeActions.testFlag(RA_Resize)){ QSize newSize = m_size * scale;if(minimumSize().width() > newSize.width()){name::setMinimumSize(newSize);}name::resize(newSize);}\
|
||
if (m_sizeActions.testFlag(RA_MinimumSize)){Qss##name::setMinimumSize(m_minimumSize * scale);}\
|
||
if (m_sizeActions.testFlag(RA_MinimumHeight)){Qss##name::setMinimumHeight(m_minimumSize.height() * scale);}\
|
||
if (m_sizeActions.testFlag(RA_MinimumWidth)){Qss##name::setMinimumWidth(m_minimumSize.width() * scale);}\
|
||
if (m_sizeActions.testFlag(RA_MaximumSize)){Qss##name::setMaximumSize(m_maximumSize * scale);}\
|
||
if (m_sizeActions.testFlag(RA_MaximumHeight)){Qss##name::setMaximumHeight(m_maximumSize.height() * scale);}\
|
||
if (m_sizeActions.testFlag(RA_MaximumWidth)){ Qss##name::setMaximumWidth(m_maximumSize.width() * scale); }\
|
||
cale = scale;
|
||
|
||
typedef class ICallDPIChanged
|
||
{
|
||
virtual void ScaleChanged(float scale) = 0;
|
||
virtual WId GetWID() const = 0;
|
||
virtual void SetScale(float scale) = 0;
|
||
protected:
|
||
uint32_t m_sizeActions;
|
||
float cale = 1;
|
||
QSize m_size;
|
||
QSize m_minimumSize;
|
||
QSize m_maximumSize;
|
||
}QssCallDpiChanged;
|
||
|
||
typedef class IDPIHelper
|
||
{
|
||
virtual bool DPIChanged(unsigned short, WId) = 0;
|
||
virtual void RemoveDPIRecord(WId) = 0;//移除指定native窗体的DPI记录 一般用于native窗体析构时
|
||
virtual float GetDPIScale(WId) const = 0;
|
||
virtual float GetOldDPIScale(WId) const = 0;
|
||
virtual QString GetStyleSheet(WId) const = 0;//获取指定DPI下的样式表
|
||
virtual float GetScaleNumber(float, WId) const = 0;//获取指定DPI下的数值 缩放后数值
|
||
virtual QList<WId> GetAllWindowID() const = 0;//获取所有自己加载过皮肤的窗口ID
|
||
|
||
//优化接口 主要是为了适配用户主机只有一种DPI时使用
|
||
virtual bool IsOnlyOneDPI() const = 0;//获取用户主机是否只有一种DPI
|
||
virtual void RefrushDPIRecords() = 0;//显示器数量发生了变化 刷新历史显示器DPI记录
|
||
virtual void SetDefaultScale(float scale) = 0;//设置缺省DPI值 当显示器dpi只有一种时刷新
|
||
virtual float GetDefaultScale() const = 0;//获取缺省DPI缩放值 只有当机器上所有的显示器为统一dpi时起作用
|
||
}QssDpiHelper;
|
||
|
||
IDPIHelper * GetDPIHelper();
|
||
#define DPIHelper() GetDPIHelper()
|
||
class QssPushButton : public QPushButton{
|
||
public:
|
||
QssPushButton(QWidget *parent,QString objName);
|
||
|
||
};
|
||
|
||
class QssTtitleBar : public QWidget
|
||
{
|
||
Q_OBJECT
|
||
|
||
signals:
|
||
void OnMaxOrRestore(bool );
|
||
public:
|
||
enum QTitleBar_Button
|
||
{
|
||
QTitleBar_Button_Min = 0x00000001,
|
||
QTitleBar_Button_Max = 0x00000002,
|
||
QTitleBar_Button_Restore = 0x00000004,
|
||
QTitleBar_Button_Close = 0x00000008
|
||
};
|
||
|
||
enum QTitleBar_Type
|
||
{
|
||
QTitleBar_Type_MainWindow = QTitleBar_Button_Min |
|
||
QTitleBar_Button_Max |QTitleBar_Button_Restore | QTitleBar_Button_Close,
|
||
QTitleBar_Type_Dialog = QTitleBar_Button_Close,
|
||
QTitleBar_Type_MessageBox = QTitleBar_Button_Close
|
||
};
|
||
|
||
QssTtitleBar(QWidget *parent, QTitleBar_Type type = QTitleBar_Type_MainWindow);
|
||
~QssTtitleBar();
|
||
|
||
void setTitle(QString title);
|
||
void setIcon( QIcon icon);
|
||
|
||
void setMaxOrRestore(bool val);
|
||
bool maxOrRestore(){return m_maxOrRestore;}
|
||
void SetMainWindow(QMainWindow*);
|
||
QRect& normalRect(){return m_rcNormal;}
|
||
|
||
private slots:
|
||
void onMaxOrRestore();
|
||
|
||
protected:
|
||
void paintEvent(QPaintEvent *);
|
||
void mouseMoveEvent(QMouseEvent * ev);
|
||
void mousePressEvent(QMouseEvent * ev);
|
||
void mouseReleaseEvent(QMouseEvent * ev);
|
||
bool eventFilter(QObject * obj, QEvent * ev);
|
||
|
||
private:
|
||
QPushButton* m_closeBtn;
|
||
QPushButton* m_maxBtn;
|
||
QPushButton* m_restoreBtn;
|
||
QPushButton* m_minBtn;
|
||
|
||
QLabel* m_titlebarTitle;
|
||
QMainWindow *m_Main;
|
||
bool m_maxOrRestore;
|
||
bool m_pressed;
|
||
|
||
QPoint m_pressedPos;
|
||
|
||
QRect m_rcValid;//桌面最大可用尺寸
|
||
QRect m_rcNormal;//还原后窗口尺寸
|
||
|
||
QTitleBar_Type m_type;
|
||
};
|
||
class QssEventFilter
|
||
: public QAbstractNativeEventFilter
|
||
{
|
||
public:
|
||
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
|
||
{/*
|
||
MSG* pMsg = reinterpret_cast<MSG*>(message);
|
||
if(nullptr != pMsg){
|
||
switch (pMsg->message)
|
||
{
|
||
case WM_DPICHANGED:
|
||
{
|
||
qDebug()<<"DPI CHANGED";
|
||
|
||
}
|
||
}
|
||
}*/
|
||
// TODO: filter out or modify msg struct here
|
||
return false;
|
||
}
|
||
};
|
||
|
||
class QssMainWindow : public QMainWindow,ICallDPIChanged
|
||
{
|
||
Q_OBJECT
|
||
|
||
public slots:
|
||
void OnMaxOrRestore(bool max);
|
||
public:
|
||
typedef enum{
|
||
EVENT_MOVE = 523,
|
||
} EVENT_CUSTOM;
|
||
QssMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0,float scale = 1);
|
||
virtual ~QssMainWindow();
|
||
|
||
QWidget *TitleBar();
|
||
void ShowMask();
|
||
void HideMask();
|
||
void show();
|
||
void showMinimized();
|
||
void showMaximized();
|
||
void showFullScreen();
|
||
void showNormal();
|
||
void setCursorShape(int CalPos) ;
|
||
void setWindowTitle( QString title );
|
||
void setWindowIcon( QIcon icon );
|
||
int CalCursorPos(QPoint pt, int colPos);
|
||
void SetTitleHeight(uint32_t height);
|
||
inline QssTtitleBar* titleBar(){return m_titleBar;}
|
||
inline QFrame* frame(){return m_frame;}
|
||
int CalCursorCol(QPoint pt); //计算鼠标X的位置
|
||
virtual bool eventFilter(QObject * obj, QEvent * ev);
|
||
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
|
||
|
||
private:
|
||
void onMouseMoveEvent(QMouseEvent * ev);
|
||
void onMousePressEvent(QMouseEvent * ev);
|
||
void onMouseReleaseEvent(QMouseEvent * ev);
|
||
protected:
|
||
QFrame* m_frame;
|
||
QRect mFrameRect;
|
||
QRect mRect;
|
||
QRect m_CentralRect;
|
||
QssTtitleBar* m_titleBar;
|
||
void showEvent(QShowEvent *ev);
|
||
|
||
virtual void ScaleChanged(float scale) ;
|
||
virtual WId GetWID() const;
|
||
virtual void SetScale(float scale) ;
|
||
virtual void paintEvent(QPaintEvent *event);
|
||
|
||
private:
|
||
QRect m_rcValid;//桌面最大可用尺寸
|
||
QRect m_rcNormal;//还原后窗口尺寸
|
||
QRect m_rcNormalCentral;//还原后central widget的尺寸
|
||
/** 边框调整大小相关 */
|
||
QPoint m_pos;
|
||
bool m_mousePressedInBoundy;
|
||
bool m_left,m_right,m_top,m_bottom;
|
||
|
||
int m_iCalCursorPos;
|
||
bool m_bLeftPress;
|
||
QRect m_rtPreGeometry;
|
||
QPoint m_ptViewMousePos;
|
||
float m_scale;
|
||
QWidget *mShadowMask;
|
||
|
||
};
|
||
|
||
class QssDialog : public QDialog
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
QssDialog(QWidget *parent);
|
||
virtual ~QssDialog();
|
||
|
||
void ShowMask();
|
||
void HideMask();
|
||
|
||
void show();
|
||
void raise();
|
||
void activateWindow();
|
||
|
||
int exec();
|
||
|
||
void setWindowTitle( QString title );
|
||
void setWindowIcon( QIcon icon );
|
||
|
||
inline QssTtitleBar* titleBar(){return m_titleBar;}
|
||
inline QFrame* frame(){return m_frame;}
|
||
|
||
virtual bool eventFilter(QObject * obj, QEvent * ev);
|
||
|
||
private:
|
||
void onMouseMoveEvent(QMouseEvent * ev);
|
||
void onMousePressEvent(QMouseEvent * ev);
|
||
void onMouseReleaseEvent(QMouseEvent * ev);
|
||
|
||
private:
|
||
QWidget* m_parent;
|
||
|
||
QFrame* m_frame;
|
||
QssTtitleBar* m_titleBar;
|
||
|
||
QRect m_rcValid;
|
||
|
||
/** 边框调整大小相关 */
|
||
QRect mFrameRect;
|
||
QPoint m_pos;
|
||
bool m_mousePressedInBorder;
|
||
bool m_left,m_right,m_top,m_bottom;
|
||
QWidget *mShadowMask;
|
||
|
||
};
|
||
|
||
|
||
// 可停靠widget
|
||
class QssDockWidget : public QDockWidget
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
QssDockWidget(QWidget *parent);
|
||
|
||
void ShowMask();
|
||
void HideMask();
|
||
virtual ~QssDockWidget();
|
||
|
||
void show();
|
||
void raise();
|
||
void activateWindow();
|
||
|
||
int exec();
|
||
|
||
void setWindowTitle( QString title );
|
||
void setWindowIcon( QIcon icon );
|
||
void paintEvent(QPaintEvent *);
|
||
inline QssTtitleBar* titleBar(){return m_titleBar;}
|
||
inline QFrame* frame(){return m_frame;}
|
||
|
||
virtual bool eventFilter(QObject * obj, QEvent * ev);
|
||
|
||
private:
|
||
void onMouseMoveEvent(QMouseEvent * ev);
|
||
void onMousePressEvent(QMouseEvent * ev);
|
||
void onMouseReleaseEvent(QMouseEvent * ev);
|
||
|
||
private:
|
||
QFrame* m_frame;
|
||
QssTtitleBar* m_titleBar;
|
||
|
||
QRect m_rcValid;
|
||
QWidget* m_parent;
|
||
|
||
/** 边框调整大小相关 */
|
||
QRect mFrameRect;
|
||
QPoint m_pos;
|
||
bool m_mousePressedInBorder;
|
||
bool m_left,m_right,m_top,m_bottom;
|
||
QWidget *mShadowMask;
|
||
|
||
};
|
||
|
||
class QssMessageBox : public QMessageBox
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
explicit QssMessageBox(QWidget *parent = 0);
|
||
QssMessageBox(Icon icon, const QString &title, const QString &text,
|
||
StandardButtons buttons = NoButton, QWidget *parent = 0,
|
||
Qt::WindowFlags flags = Qt::Widget | Qt::FramelessWindowHint);
|
||
~QssMessageBox();
|
||
|
||
inline QssTtitleBar* titleBar(){return m_titleBar;}
|
||
inline QFrame* frame(){return m_frame;}
|
||
|
||
static QMessageBox::StandardButton tips(const QString & text, QWidget* parent = 0,
|
||
const QString & title = QString::fromLocal8Bit("提示"), StandardButtons btn = QMessageBox::Ok);
|
||
static QMessageBox::StandardButton warn(const QString & text, QWidget* parent = 0,
|
||
const QString & title = QString::fromLocal8Bit("警告"), StandardButtons btn = QMessageBox::Ok);
|
||
static QMessageBox::StandardButton error(const QString & text, QWidget* parent = 0,
|
||
const QString & title = QString::fromLocal8Bit("错误"), StandardButtons btn = QMessageBox::Ok);
|
||
static QMessageBox::StandardButton ask(const QString & text, QWidget* parent = 0,
|
||
const QString & title = QString::fromLocal8Bit("询问"), StandardButtons btn = QMessageBox::Yes | QMessageBox::No);
|
||
|
||
/** 覆盖定义,适配原有QMessageBox */
|
||
static StandardButton information(QWidget *parent, const QString &title,
|
||
const QString &text, StandardButtons buttons = Ok,
|
||
StandardButton defaultButton = NoButton);
|
||
static StandardButton question(QWidget *parent, const QString &title,
|
||
const QString &text, StandardButtons buttons = QMessageBox::Ok,
|
||
StandardButton defaultButton = QMessageBox::NoButton);
|
||
static StandardButton warning(QWidget *parent, const QString &title,
|
||
const QString &text, StandardButtons buttons = QMessageBox::Ok,
|
||
StandardButton defaultButton = QMessageBox::NoButton);
|
||
static StandardButton critical(QWidget *parent, const QString &title,
|
||
const QString &text, StandardButtons buttons = QMessageBox::Ok,
|
||
StandardButton defaultButton = QMessageBox::NoButton);
|
||
|
||
static QMessageBox::StandardButton regard(const QString & text, QWidget* parent = 0,
|
||
const QString & title = QString::fromLocal8Bit("关于"));
|
||
static QMessageBox::StandardButton regard(const QString & text, QIcon icon, QWidget* parent = 0,
|
||
const QString & title = QString::fromLocal8Bit("关于"));
|
||
|
||
static QMessageBox::StandardButton regardQt(QWidget* parent = 0,
|
||
const QString & title = QString::fromLocal8Bit("关于Qt"));
|
||
|
||
static void about(QWidget *parent, const QString &title, const QString &text);
|
||
static void about(QWidget *parent, const QString &title, const QString &text, QIcon icon);
|
||
|
||
static void aboutQt(QWidget *parent, const QString &title = QString());
|
||
|
||
bool eventFilter(QObject * obj, QEvent * ev);
|
||
|
||
private:
|
||
QFrame* m_frame;
|
||
QssTtitleBar* m_titleBar;
|
||
QWidget* m_parent;
|
||
|
||
QRect m_rcValid;
|
||
};
|
||
|
||
|
||
|
||
class QssMaskWidget : public QWidget
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
QssMaskWidget(QWidget *parent = Q_NULLPTR);
|
||
virtual ~QssMaskWidget();
|
||
virtual bool eventFilter(QObject * obj, QEvent * ev);
|
||
|
||
public:
|
||
|
||
protected:
|
||
virtual void paintEvent(QPaintEvent *event);
|
||
|
||
private:
|
||
QWidget *mParent;
|
||
Ui::Toast ui;
|
||
};
|
||
|
||
class QssToastWidget : public QWidget
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
QssToastWidget(QWidget *parent = Q_NULLPTR);
|
||
~QssToastWidget();
|
||
|
||
void setText(const QString& text);
|
||
|
||
void showAnimation(int timeout = 2000);// 动画方式show出,默认2秒后消失
|
||
|
||
public:
|
||
// 静态调用
|
||
static void showTip(const QString& text, QWidget* parent = nullptr);
|
||
|
||
protected:
|
||
virtual void paintEvent(QPaintEvent *event);
|
||
|
||
private:
|
||
Ui::Toast ui;
|
||
};
|
||
|
||
|
||
|
||
class QSSProcessBar : public QDialog
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
explicit QSSProcessBar(QWidget *parent = nullptr);
|
||
~QSSProcessBar();
|
||
void showEvent(QShowEvent *) override;
|
||
|
||
public slots:
|
||
void on_percent(int);
|
||
void on_done_close();
|
||
private:
|
||
Ui::Process *ui;
|
||
QWidget *mParent;
|
||
};
|
||
|
||
// 异步执行任务,不会阻塞ui线程
|
||
class QSSASyncProcess : public QObject{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
QSSASyncProcess(QWidget *parent = nullptr);
|
||
~QSSASyncProcess();
|
||
int Start(void*);
|
||
signals:
|
||
void DonePercent(int);
|
||
void Done();
|
||
void StartRun(void *);
|
||
public slots:
|
||
virtual void Run(void *) ;
|
||
protected:
|
||
QWidget *mParent;
|
||
QThread mThread;
|
||
};
|
||
|
||
#define tipBox(text) QssMessageBox::tips(text)
|
||
#define warnBox(text) QssMessageBox::warn(text)
|
||
#define errBox(text) QssMessageBox::error(text)
|
||
#define askBox(text) QssMessageBox::ask(text)
|
||
|
||
#define aboutBox(title, text) QssMessageBox::regard(text, 0,title)
|
||
#define aboutQtBox() QssMessageBox::regardQt()
|
||
|
||
#endif // QSS_H
|