若該文為原創文章,轉載請注明原文出處
Qt開發專欄:開發技術(點選傳送門)
需求
手機模拟器伸縮旋轉架構,中間為容器區域預留,給手機模拟器;
目标效果

功能
1.四個角滑鼠圖示切換,并且點選可拉伸;
2.手機框區域,滑鼠點選可以拽托;
3.透明視窗的使用;
4.橫豎屏的切換,,使用F1功能鍵;
原理
使用QRegion和QRect對滑鼠區域進行判斷;
使用QPainter進行繪制;
使用qss定制按鈕樣式;
對QWidget的paintEvent和resizeEvent使用;
涉及技術博文
《Qt實用技巧:在Qt中擷取螢幕的絕對坐标》
《Qt開發技術:Qt繪圖系統(一)繪圖系統介紹》
《Qt開發技術:Qt繪圖系統(二)QPainter詳解》
《qss樣式表筆記大全(一):qss名詞解析(包含相關示例)》
《Qt實用技巧:實作視窗透明的五種方法》
《Qt實用技巧:組合圖形的比例變換》
《Qt實用技巧:實作不規則視窗的滑鼠消息穿透,包括穿透到桌面和穿透到父視窗》
Demo:手機模拟器拉伸旋轉架構 v1.0.0
體驗下載下傳位址
QQ群:1047134658(點選“檔案”搜尋“MobileFrame”,群内與博文同步更新)
核心代碼
MobileWidget.h
#ifndef MOBILEWIDGET_H
#define MOBILEWIDGET_H
#include <QWidget>
#include <QPainter>
#include <QMouseEvent>
namespace Ui {
class MobileWidget;
}
class MobileWidget : public QWidget
{
Q_OBJECT
public:
enum DIRECT {
DIRECT_VERTICAL = 0x00,
DIRECT_HORIZONTAL = 0x01,
};
public:
explicit MobileWidget(QWidget *parent = 0);
~MobileWidget();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent *event);
void keyPressEvent(QKeyEvent *event);
protected:
void drawBackground(QPainter *painter);
private:
Ui::MobileWidget *ui;
int _minWidth; // 最小寬度
int _minHeight; // 最小高度
int _radius; // 圓角角度
int _spaceWidth; // 圓角到中間的邊框高度
int _borderWidth; // 兩邊窄邊的寬度
int _earY; // 耳機框的y坐标
int _earWidth; // 耳機框的寬度
int _earHeight; // 耳機框的高度
bool _vertical;
QColor _transparentColor; // 四個直角透明區域顔色
QRect _cornerRect1; // 四個圓角區域矩形 1->2->3->4 = 左上->右上->左下->右下
QRect _cornerRect2; // 四個圓角區域矩形
QRect _cornerRect3; // 四個圓角區域矩形
QRect _cornerRect4; // 四個圓角區域矩形
QRect _borderRect1; // 左邊界
QRect _borderRect2; // 右邊界
QRect _topBorderRect1; // 頂部邊框圓角部分
QRect _topBorderRect2; // 頂部邊框圓角下部
QRect _bottomBorderRect1; // 底部邊框圓角部分
QRect _bottomBorderRect2; // 底部邊框圓角上部
QRect _centerRect; // 中心容器區域
QRect _earRect; // 耳機框區域
QRegion _moveRegion; // 滑鼠點選可移動的區域
QRegion _stretchRegion1; // 滑鼠點選可拉伸的區域
QRegion _stretchRegion2; // 滑鼠點選可拉伸的區域
QRegion _stretchRegion3; // 滑鼠點選可拉伸的區域
QRegion _stretchRegion4; // 滑鼠點選可拉伸的區域
bool _leftButtonPressed; // 滑鼠左鍵按鈕
QPoint _beginPoint; // 滑鼠左鍵按鈕按下時的坐标
QPoint _leftTopPoint; // 視窗左上角的坐标
bool _stretchRegion1Pressed;// 拉伸按鈕區域
bool _stretchRegion2Pressed;// 拉伸按鈕區域
bool _stretchRegion3Pressed;// 拉伸按鈕區域
bool _stretchRegion4Pressed;// 拉伸按鈕區域
QRect _beginRect; // 拉伸開始時的原始視窗
DIRECT _direct; // 方向是水準還是垂直
QRect _buttonRectIcon;
QRect _buttonRectService;
QRect _buttonRectMax;
QRect _buttonRectMin;
QRect _buttonRectExit;
QRect _buttonRectLeft;
QRect _buttonRectMiddle;
QRect _buttonRectRight;
};
#endif // MOBILEWIDGET_H
MobileWidget.cpp
#include "MobileWidget.h"
#include "ui_MobileWidget.h"
#include <QDebug>
MobileWidget::MobileWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MobileWidget),
_minWidth(400),
_minHeight(400),
_radius(50),
_spaceWidth(35),
_borderWidth(3),
_earY(30),
_earWidth(100),
_earHeight(10),
_transparentColor(QColor("#02000000")),
_leftButtonPressed(false),
_stretchRegion1Pressed(false),
_stretchRegion2Pressed(false),
_stretchRegion3Pressed(false),
_stretchRegion4Pressed(false),
_direct(DIRECT::DIRECT_VERTICAL)
{
ui->setupUi(this);
setWindowFlag(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
setMouseTracking(true);
setMinimumSize(_minWidth, _minHeight);
}
MobileWidget::~MobileWidget()
{
delete ui;
}
...
void MobileWidget::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
if(_moveRegion.contains(event->pos()))
{
_leftButtonPressed = true;
}
if(_stretchRegion1.contains(event->pos()))
{
_stretchRegion1Pressed = true;
}else if(_stretchRegion2.contains(event->pos()))
{
_stretchRegion2Pressed = true;
}else if(_stretchRegion3.contains(event->pos()))
{
_stretchRegion3Pressed = true;
}else if(_stretchRegion4.contains(event->pos()))
{
_stretchRegion4Pressed = true;
}
_beginPoint = QCursor::pos();
_leftTopPoint = geometry().topLeft();
_beginRect = geometry();
}
QWidget::mousePressEvent(event);
}
...
void MobileWidget::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
_leftButtonPressed = false;
_stretchRegion1Pressed = false;
_stretchRegion2Pressed = false;
_stretchRegion3Pressed = false;
_stretchRegion4Pressed = false;
}
QWidget::mouseReleaseEvent(event);
}
...
void MobileWidget::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_F1)
{
qDebug() << __FILE__ << __LINE__;
if(_direct == DIRECT_HORIZONTAL)
{
_direct = DIRECT_VERTICAL;
int width = rect().width();
int height = rect().height();
resize(height, width);
}else if(_direct == DIRECT_VERTICAL)
{
_direct = DIRECT_HORIZONTAL;
int width = rect().width();
int height = rect().height();
resize(height, width);
}
}
}