【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

相关文章

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

MySQL高级查询之JOIN、子查询、窗口函数实际案例

《MySQL高级查询之JOIN、子查询、窗口函数实际案例》:本文主要介绍MySQL高级查询之JOIN、子查询、窗口函数实际案例的相关资料,JOIN用于多表关联查询,子查询用于数据筛选和过滤,窗口函... 目录前言1. JOIN(连接查询)1.1 内连接(INNER JOIN)1.2 左连接(LEFT JOI

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

Qt spdlog日志模块的使用详解

《Qtspdlog日志模块的使用详解》在Qt应用程序开发中,良好的日志系统至关重要,本文将介绍如何使用spdlog1.5.0创建满足以下要求的日志系统,感兴趣的朋友一起看看吧... 目录版本摘要例子logmanager.cpp文件main.cpp文件版本spdlog版本:1.5.0采用1.5.0版本主要

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA