【Qt编程】基于Qt的词典开发系列四--无边框窗口的缩放与拖动

2024-03-24 15:08

本文主要是介绍【Qt编程】基于Qt的词典开发系列四--无边框窗口的缩放与拖动,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在现在,绝大多数软件都向着简洁,时尚发展。就拿有道的单词本和我做的单词本来说,绝大多数用户肯定喜欢我所做的单词本(就单单界面,关于颜色搭配和布局问题,大家就不要在意了)。

有道的单词本:


我所做的单词本:


很明显,两者的主要区别就是周围的边框问题。你可以对比QQ以前的版本和这几年的版本,就会发现都倾向于下面这种窗口模式。下面我们就说说如何用Qt实现无边框窗口的缩放与拖动。

对于无边框窗口的拖动其实很简单,其基本思想是,在鼠标移动前后记录鼠标的坐标,然后将窗口移动这两个坐标之差的距离即可,具体实现可以看代码,就非常清楚了。下面主要讲讲如何实现鼠标改变窗口的大小,首先,我们将一个窗口分为以下9个区域,其中只有鼠标在22区域时无法改变其形状,不能改变窗口大小。当鼠标在其它区域时,鼠标改变形状并可以改变窗口大小。窗口区域分类如下图:


具体实现如下代码(widget.ui未做任何改变):
1、widget.h文件
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#define MARGIN 20//四个角的长度
namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();int countFlag(QPoint p, int row);void setCursorType(int flag);int countRow(QPoint p);protected:void mousePressEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);void mouseDoubleClickEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);
private:Ui::Widget *ui;bool isLeftPressed;int curPos;QPoint pLast;
};#endif // WIDGET_H

2、widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include<QMouseEvent>
#include<QDebug>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);this->setMouseTracking(true);//设置在不按鼠标的情况下也触发鼠标移动事件,注意QMainWindow的情况:centralWidget()->setMouseTracking(true);isLeftPressed=false;curPos=0;//标记鼠标左击时的位置this->setMinimumSize(400,300);//设置最小尺寸QCursor cursor;cursor.setShape(Qt::ArrowCursor);//设置鼠标为箭头形状// ui->pushButton->setCursor(cursor);//当放在按钮上时,为箭头// cursor.setShape(Qt::OpenHandCursor);QWidget::setCursor(cursor);//当放在主窗口上时,为手形qDebug()<<"h="<<this->height();setWindowFlags(Qt::FramelessWindowHint);//设置主窗口无边框qDebug()<<this->minimumHeight();
}Widget::~Widget()
{delete ui;
}
void Widget::mousePressEvent(QMouseEvent *event)//鼠标按下事件
{if(event->button()==Qt::LeftButton){this->isLeftPressed=true;QPoint temp=event->globalPos();pLast=temp;curPos=countFlag(event->pos(),countRow(event->pos()));event->ignore();}
}void Widget::mouseReleaseEvent(QMouseEvent *event)//鼠标释放事件
{if(isLeftPressed)isLeftPressed=false;QApplication::restoreOverrideCursor();//恢复鼠标指针性状event->ignore();
}void Widget::mouseDoubleClickEvent(QMouseEvent *event)//鼠标双击 全屏
{if(event->button()==Qt::LeftButton){if(windowState()!=Qt::WindowFullScreen)setWindowState(Qt::WindowFullScreen);else setWindowState(Qt::WindowNoState);//恢复正常模式}event->ignore();
}void Widget::mouseMoveEvent(QMouseEvent *event)//鼠标移动事件
{int poss=countFlag(event->pos(),countRow(event->pos()));setCursorType(poss);if(isLeftPressed)//是否左击{QPoint ptemp=event->globalPos();ptemp=ptemp-pLast;if(curPos==22)//移动窗口{ptemp=ptemp+pos();move(ptemp);}else{QRect wid=geometry();switch(curPos)//改变窗口的大小{case 11:wid.setTopLeft(wid.topLeft()+ptemp);break;//左上角case 13:wid.setTopRight(wid.topRight()+ptemp);break;//右上角case 31:wid.setBottomLeft(wid.bottomLeft()+ptemp);break;//左下角case 33:wid.setBottomRight(wid.bottomRight()+ptemp);break;//右下角case 12:wid.setTop(wid.top()+ptemp.y());break;//中上角case 21:wid.setLeft(wid.left()+ptemp.x());break;//中左角case 23:wid.setRight(wid.right()+ptemp.x());break;//中右角case 32:wid.setBottom(wid.bottom()+ptemp.y());break;//中下角}setGeometry(wid);}pLast=event->globalPos();//更新位置}event->ignore();
}int Widget::countFlag(QPoint p,int row)//计算鼠标在哪一列和哪一行
{if(p.y()<MARGIN)return 10+row;else if(p.y()>this->height()-MARGIN)return 30+row;elsereturn 20+row;
}void Widget::setCursorType(int flag)//根据鼠标所在位置改变鼠标指针形状
{Qt::CursorShape cursor;switch(flag){case 11:case 33:cursor=Qt::SizeFDiagCursor;break;case 13:case 31:cursor=Qt::SizeBDiagCursor;break;case 21:case 23:cursor=Qt::SizeHorCursor;break;case 12:case 32:cursor=Qt::SizeVerCursor;break;case 22:cursor=Qt::OpenHandCursor;break;default://  QApplication::restoreOverrideCursor();//恢复鼠标指针性状break;}setCursor(cursor);
}int Widget::countRow(QPoint p)//计算在哪一列
{return (p.x()<MARGIN)?1:(p.x()>(this->width()-MARGIN)?3:2);
}
3、main.cpp文件

#include<QtWidgets>
#include "widget.h"
int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

程序运行截图如下:


        当你将鼠标放在窗口的边缘时,鼠标会变化形状,表示可以拖动窗口。由于没有关闭窗口,只能在强制关闭窗口。如果想做到和不同窗口实现最小化和关闭窗口的画,我们可以在窗口左上角放置两个ToolButton,并设置autorise属性,加上图片即可。下面给出使用上面的无边框窗口所做的词典软件的主界面:



基于Qt的词典开发系列

  1. 词典框架设计及成品展示
  2. 本地词典的设计
  3. 开始菜单的设计
  4. 无边框窗口的缩放与拖动
  5. 无边框窗口的拖动
  6. 界面美化设计
  7. 调用网络API
  8. 用户登录及API调用的实现
  9. JSON数据解析
  10. 国际音标的显示
  11. 系统托盘的显示
  12. 调用讲述人
  13. 音频播放
  14. 自动补全功能
  15. HTML特殊字符及正则表达式
  16. 后序
作品下载地址(发布版)http://download.csdn.net/detail/tengweitw/8548767
作品下载地址(绿色版)http://download.csdn.net/detail/tengweitw/8830495
源码下载地址http://download.csdn.net/detail/tengweitw/8830503

原文:http://blog.csdn.net/tengweitw/article/details/38758051

作者:nineheadedbird




这篇关于【Qt编程】基于Qt的词典开发系列四--无边框窗口的缩放与拖动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/841969

相关文章

PostgreSQL中rank()窗口函数实用指南与示例

《PostgreSQL中rank()窗口函数实用指南与示例》在数据分析和数据库管理中,经常需要对数据进行排名操作,PostgreSQL提供了强大的窗口函数rank(),可以方便地对结果集中的行进行排名... 目录一、rank()函数简介二、基础示例:部门内员工薪资排名示例数据排名查询三、高级应用示例1. 每

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

Qt QCustomPlot库简介(最新推荐)

《QtQCustomPlot库简介(最新推荐)》QCustomPlot是一款基于Qt的高性能C++绘图库,专为二维数据可视化设计,它具有轻量级、实时处理百万级数据和多图层支持等特点,适用于科学计算、... 目录核心特性概览核心组件解析1.绘图核心 (QCustomPlot类)2.数据容器 (QCPDataC

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

SpringBoot开发中十大常见陷阱深度解析与避坑指南

《SpringBoot开发中十大常见陷阱深度解析与避坑指南》在SpringBoot的开发过程中,即使是经验丰富的开发者也难免会遇到各种棘手的问题,本文将针对SpringBoot开发中十大常见的“坑... 目录引言一、配置总出错?是不是同时用了.properties和.yml?二、换个位置配置就失效?搞清楚加

Qt如何实现文本编辑器光标高亮技术

《Qt如何实现文本编辑器光标高亮技术》这篇文章主要为大家详细介绍了Qt如何实现文本编辑器光标高亮技术,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录实现代码函数作用概述代码详解 + 注释使用 QTextEdit 的高亮技术(重点)总结用到的关键技术点应用场景举例示例优化建议

Qt 设置软件版本信息的实现

《Qt设置软件版本信息的实现》本文介绍了Qt项目中设置版本信息的三种常用方法,包括.pro文件和version.rc配置、CMakeLists.txt与version.h.in结合,具有一定的参考... 目录在运行程序期间设置版本信息可以参考VS在 QT 中设置软件版本信息的几种方法方法一:通过 .pro

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部