需求

  手机模拟器伸缩旋转框架,中间为容器区域预留,给手机模拟器;

 

目标效果

  

 

功能

  1.四个角鼠标图标切换,并且点击可拉伸;
  2.手机框区域,鼠标点击可以拽托;
  3.透明窗口的使用;
  4.横竖屏的切换,,使用F1功能键;

 

原理

  使用QRegion和QRect对鼠标区域进行判断;
  使用QPainter进行绘制;
  使用qss定制按钮样式;
  对QWidget的paintEvent和resizeEvent使用;

 

涉及技术博文

Demo:手机模拟器拉伸旋转框架 v1.0.0

  

 

体验下载地址

  CSDN:https://download.csdn.net/download/qq21497936/12530739
  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);
} }
}
 

项目实战:Qt手机模拟器拉伸旋转框架的更多相关文章

  1. Android项目实战_手机安全卫士splash界面

    - 根据代码的类型组织包结构 1. 界面 com.hb.mobilesafe.activities 2. 服务 com.hb.mobilesafe.services 3. 业务逻辑 com.hb.mo ...

  2. Android项目实战_手机安全卫士程序锁

    ###1.两个页面切换的实现1. 可以使用Fragment,调用FragmentTransaction的hide和show方法2. 可以使用两个布局,设置visibility的VISIABLE和INV ...

  3. Android项目实战_手机安全卫士系统加速

    ## 1.本地数据库自动更新的工作机制1. 开启一个服务,定时访问服务器2. 进行版本对比,如果最新版本比较高,获取需要更新的内容3. 将新内容插入到本地数据库中 ## 2.如何处理横竖屏切换1. 指 ...

  4. Android项目实战_手机安全卫士拦截骚扰

    ###1.骚扰拦截需求分析1.界面1.1 黑名单列表界面1.2 添加黑名单界面2.功能2.1 黑名单的添加.删除2.2 拦截电话2.3 拦截短信 ###2.黑名单数据库的创建1.分析需要的字段id 主 ...

  5. MVC + EFCore 项目实战 - 数仓管理系统2- 搭建基本框架配置EFCore

    本次课程就正式进入开发部分. 首先我们先搭建项目框架,还是和之前渐进式风格保持一致,除必备组件外,尽量使用原生功能以方便大家理解. 开发工具:vs 2019 或以上 数据库:SQL SERVER 20 ...

  6. Android项目实战_手机安全卫士软件管家

    ###1.应用程序信息的flags 1. int flags = packageInfo.applicationInfo.flags2. 0000 0000 0000 0000 0000 0000 0 ...

  7. Android项目实战_手机安全卫士手机防盗界面

    #安全卫士手机防盗# ###1.Activity的任务栈 1.类似一个木桶,每层只能放一个木块,我们放入木块和取出木块的时候只能从最上面开始操作 ###2.Android中的坐标系![](http:/ ...

  8. Android项目实战_手机安全卫士home界面

    # 安全卫士主页面# ###1.GridView控件 1.与ListView的使用方式差不多,也要使用数据适配器,通过设置android:numColumns控制显示几列 2.通过指定android: ...

  9. Android项目实战_手机安全卫士流量统计

    ## 1.抽屉控件SlidingDrawer:一定要配置android:handle(把手)和android:content(内容),并在子View中添加把手和内容的布局```java <Sli ...

随机推荐

  1. Kubernetes实战 - 从零开始搭建微服务 - 1.5 提高可用性-发布多节点的Node/Express网络应用程序

    1.5 提高可用性-发布多节点的Node/Express网络应用程序 Kubernetes实战 - 从零开始搭建微服务 前言 在上一篇文章中,已经学习了如何简单地开发一个单层网络应用.[Kuberne ...

  2. SpringCloud Alibaba 简介

    SpringCloud Aliababa简介 SpringCloud Alibaba是阿里巴巴集团开源的一套微服务架构解决方案. 微服务架构是为了更好的分布式系统开发,将一个应用拆分成多个子应用,每一 ...

  3. 8分钟为你详解React、Angular、Vue三大前端技术

    [引言] 当前世界中,技术发展非常迅速并且变化迅速,开发者需要更多的开发工具来解决不同的问题.本文就对于当下主流的前端开发技术React.Vue.Angular这三个框架做个相对详尽的探究,目的是为了 ...

  4. [PHP学习教程 - 数字]001.数字补0(Num padding)

    引言:在日常工作中,经常要用到数字前后补0的操作,如:日期格式yyyy-MM-dd等等. 在php中有多种前后填充函数——今天,我们就介绍常用的两种,实现数字补零: str_pad sprintf 大 ...

  5. 读Pyqt4教程,带你入门Pyqt4 _013

    你是否曾经看着应用程序并思考特定的GUI项是如何产生的?大概每位程序员都这样过.然后你能看到你喜欢的GUI库提供的一系列窗口组件,但是你无法找到它.工具包通常仅仅提供最常用的窗口组件,比如按钮.文本组 ...

  6. Pytorch写CNN

    用Pytorch写了两个CNN网络,数据集用的是FashionMNIST.其中CNN_1只有一个卷积层.一个全连接层,CNN_2有两个卷积层.一个全连接层,但训练完之后的准确率两者差不多,且CNN_1 ...

  7. 初窥Ansible playbook

    Ansible是一个系列文章,我会尽量以通俗易懂.诙谐幽默的总结方式给大家呈现这些枯燥的知识点,让学习变的有趣一些. Ansible系列博文直达链接:Ansible入门系列 前言 在上一篇文章中说到A ...

  8. Java实现 LeetCode 395 至少有K个重复字符的最长子串

    395. 至少有K个重复字符的最长子串 找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k .输出 T 的长度. 示例 1: 输入: s = " ...

  9. java实现机器人行走

    某少年宫引进了一批机器人小车.可以接受预先输入的指令,按指令行动.小车的基本动作很简单,只有3种:左转(记为L),右转(记为R),向前走若干厘米(直接记数字). 例如,我们可以对小车输入如下的指令: ...

  10. Java实现除去次方数

    ** 除去次方数** 自然数的平方数是:1 4 9 16 25 - 自然数的立方数是:1 8 27 64 125 - 自然数的4次方数是:1 16 81 256 - - 这些数字都可以称为次方数. 1 ...