新增控件
This commit is contained in:
191
framelesswidget/framelesswidget.cpp
Normal file
191
framelesswidget/framelesswidget.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
#include "framelesswidget.h"
|
||||
#include "qevent.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
FramelessWidget::FramelessWidget(QObject *parent) : QObject(parent)
|
||||
{
|
||||
padding = 8;
|
||||
widget = 0;
|
||||
|
||||
pressed = false;
|
||||
pressedLeft = false;
|
||||
pressedRight = false;
|
||||
pressedTop = false;
|
||||
pressedBottom = false;
|
||||
pressedLeftTop = false;
|
||||
pressedRightTop = false;
|
||||
pressedLeftBottom = false;
|
||||
pressedRightBottom = false;
|
||||
|
||||
//如果父类是窗体则直接设置
|
||||
if (parent->isWidgetType()) {
|
||||
setWidget((QWidget *)parent);
|
||||
}
|
||||
}
|
||||
|
||||
bool FramelessWidget::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (widget != 0 && watched == widget) {
|
||||
if (event->type() == QEvent::Resize) {
|
||||
//重新计算八个描点的区域,描点区域的作用还有就是计算鼠标坐标是否在某一个区域内
|
||||
int width = widget->width();
|
||||
int height = widget->height();
|
||||
|
||||
//左侧描点区域
|
||||
rectLeft = QRectF(0, padding, padding, height - padding * 2);
|
||||
//上侧描点区域
|
||||
rectTop = QRectF(padding, 0, width - padding * 2, padding);
|
||||
//右侧描点区域
|
||||
rectRight = QRectF(width - padding, padding, padding, height - padding * 2);
|
||||
//下侧描点区域
|
||||
rectBottom = QRectF(padding, height - padding, width - padding * 2, padding);
|
||||
|
||||
//左上角描点区域
|
||||
rectLeftTop = QRectF(0, 0, padding, padding);
|
||||
//右上角描点区域
|
||||
rectRightTop = QRectF(width - padding, 0, padding, padding);
|
||||
//左下角描点区域
|
||||
rectLeftBottom = QRectF(0, height - padding, padding, padding);
|
||||
//右下角描点区域
|
||||
rectRightBottom = QRectF(width - padding, height - padding, padding, padding);
|
||||
} else {
|
||||
QMouseEvent *mouseEvent = (QMouseEvent *)event;
|
||||
if (event->type() == QEvent::MouseButtonPress) {
|
||||
//记住当前控件坐标和宽高以及鼠标按下的坐标
|
||||
rectX = widget->x();
|
||||
rectY = widget->y();
|
||||
rectW = widget->width();
|
||||
rectH = widget->height();
|
||||
lastPos = mouseEvent->pos();
|
||||
|
||||
//判断按下的手柄的区域位置
|
||||
if (rectLeft.contains(lastPos)) {
|
||||
pressedLeft = true;
|
||||
} else if (rectRight.contains(lastPos)) {
|
||||
pressedRight = true;
|
||||
} else if (rectTop.contains(lastPos)) {
|
||||
pressedTop = true;
|
||||
} else if (rectBottom.contains(lastPos)) {
|
||||
pressedBottom = true;
|
||||
} else if (rectLeftTop.contains(lastPos)) {
|
||||
pressedLeftTop = true;
|
||||
} else if (rectRightTop.contains(lastPos)) {
|
||||
pressedRightTop = true;
|
||||
} else if (rectLeftBottom.contains(lastPos)) {
|
||||
pressedLeftBottom = true;
|
||||
} else if (rectRightBottom.contains(lastPos)) {
|
||||
pressedRightBottom = true;
|
||||
} else {
|
||||
pressed = true;
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseMove) {
|
||||
//设置对应鼠标形状
|
||||
QPoint point = mouseEvent->pos();
|
||||
if (rectLeft.contains(point)) {
|
||||
widget->setCursor(Qt::SizeHorCursor);
|
||||
} else if (rectRight.contains(point)) {
|
||||
widget->setCursor(Qt::SizeHorCursor);
|
||||
} else if (rectTop.contains(point)) {
|
||||
widget->setCursor(Qt::SizeVerCursor);
|
||||
} else if (rectBottom.contains(point)) {
|
||||
widget->setCursor(Qt::SizeVerCursor);
|
||||
} else if (rectLeftTop.contains(point)) {
|
||||
widget->setCursor(Qt::SizeFDiagCursor);
|
||||
} else if (rectRightTop.contains(point)) {
|
||||
widget->setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (rectLeftBottom.contains(point)) {
|
||||
widget->setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (rectRightBottom.contains(point)) {
|
||||
widget->setCursor(Qt::SizeFDiagCursor);
|
||||
} else {
|
||||
widget->setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
//根据当前鼠标位置,计算XY轴移动了多少
|
||||
QPoint pos = mouseEvent->pos();
|
||||
int dx = pos.x() - lastPos.x();
|
||||
int dy = pos.y() - lastPos.y();
|
||||
|
||||
//根据按下处的位置判断是否是移动控件还是拉伸控件
|
||||
if (pressed) {
|
||||
widget->move(widget->x() + dx, widget->y() + dy);
|
||||
} else if (pressedLeft) {
|
||||
int resizeW = widget->width() - dx;
|
||||
if (widget->minimumWidth() <= resizeW) {
|
||||
widget->setGeometry(widget->x() + dx, rectY, resizeW, rectH);
|
||||
}
|
||||
} else if (pressedRight) {
|
||||
widget->setGeometry(rectX, rectY, rectW + dx, rectH);
|
||||
} else if (pressedTop) {
|
||||
int resizeH = widget->height() - dy;
|
||||
if (widget->minimumHeight() <= resizeH) {
|
||||
widget->setGeometry(rectX, widget->y() + dy, rectW, resizeH);
|
||||
}
|
||||
} else if (pressedBottom) {
|
||||
widget->setGeometry(rectX, rectY, rectW, rectH + dy);
|
||||
} else if (pressedLeftTop) {
|
||||
int resizeW = widget->width() - dx;
|
||||
int resizeH = widget->height() - dy;
|
||||
if (widget->minimumWidth() <= resizeW) {
|
||||
widget->setGeometry(widget->x() + dx, widget->y(), resizeW, resizeH);
|
||||
}
|
||||
if (widget->minimumHeight() <= resizeH) {
|
||||
widget->setGeometry(widget->x(), widget->y() + dy, resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedRightTop) {
|
||||
int resizeW = rectW + dx;
|
||||
int resizeH = widget->height() - dy;
|
||||
if (widget->minimumHeight() <= resizeH) {
|
||||
widget->setGeometry(widget->x(), widget->y() + dy, resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedLeftBottom) {
|
||||
int resizeW = widget->width() - dx;
|
||||
int resizeH = rectH + dy;
|
||||
if (widget->minimumWidth() <= resizeW) {
|
||||
widget->setGeometry(widget->x() + dx, widget->y(), resizeW, resizeH);
|
||||
}
|
||||
if (widget->minimumHeight() <= resizeH) {
|
||||
widget->setGeometry(widget->x(), widget->y(), resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedRightBottom) {
|
||||
int resizeW = rectW + dx;
|
||||
int resizeH = rectH + dy;
|
||||
widget->setGeometry(widget->x(), widget->y(), resizeW, resizeH);
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseButtonRelease) {
|
||||
//恢复所有
|
||||
pressed = false;
|
||||
pressedLeft = false;
|
||||
pressedRight = false;
|
||||
pressedTop = false;
|
||||
pressedBottom = false;
|
||||
pressedLeftTop = false;
|
||||
pressedRightTop = false;
|
||||
pressedLeftBottom = false;
|
||||
pressedRightBottom = false;
|
||||
widget->setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void FramelessWidget::setPadding(int padding)
|
||||
{
|
||||
this->padding = padding;
|
||||
}
|
||||
|
||||
void FramelessWidget::setWidget(QWidget *widget)
|
||||
{
|
||||
if (this->widget == 0) {
|
||||
this->widget = widget;
|
||||
//设置鼠标追踪为真
|
||||
this->widget->setMouseTracking(true);
|
||||
//绑定事件过滤器
|
||||
this->widget->installEventFilter(this);
|
||||
//设置无边框属性
|
||||
this->widget->setWindowFlags(Qt::FramelessWindowHint);
|
||||
//this->widget->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
|
||||
}
|
||||
}
|
||||
66
framelesswidget/framelesswidget.h
Normal file
66
framelesswidget/framelesswidget.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef FRAMELESSWIDGET_H
|
||||
#define FRAMELESSWIDGET_H
|
||||
|
||||
/**
|
||||
* 无边框窗体类 作者:feiyangqingyun(QQ:517216493) 2019-10-03
|
||||
* 1:可以指定需要无边框的widget
|
||||
* 2:边框四周八个方位都可以自由拉伸
|
||||
* 3:可设置对应位置的边距,以便识别更大区域
|
||||
*/
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#ifdef quc
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT FramelessWidget : public QObject
|
||||
#else
|
||||
class FramelessWidget : public QObject
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FramelessWidget(QObject *parent = 0);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
int padding; //边距
|
||||
QWidget *widget; //无边框窗体
|
||||
|
||||
bool pressed; //鼠标按下
|
||||
bool pressedLeft; //鼠标按下左侧
|
||||
bool pressedRight; //鼠标按下右侧
|
||||
bool pressedTop; //鼠标按下上侧
|
||||
bool pressedBottom; //鼠标按下下侧
|
||||
bool pressedLeftTop; //鼠标按下左上侧
|
||||
bool pressedRightTop; //鼠标按下右上侧
|
||||
bool pressedLeftBottom; //鼠标按下左下侧
|
||||
bool pressedRightBottom; //鼠标按下右下侧
|
||||
|
||||
int rectX, rectY, rectW, rectH; //窗体坐标+宽高
|
||||
QPoint lastPos; //鼠标按下处坐标
|
||||
|
||||
QRectF rectLeft; //左侧区域
|
||||
QRectF rectRight; //右侧区域
|
||||
QRectF rectTop; //上侧区域
|
||||
QRectF rectBottom; //下侧区域
|
||||
QRectF rectLeftTop; //左上侧区域
|
||||
QRectF rectRightTop; //右上侧区域
|
||||
QRectF rectLeftBottom; //左下侧区域
|
||||
QRectF rectRightBottom; //右下侧区域
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置边距
|
||||
void setPadding(int padding);
|
||||
//设置要无边框的窗体
|
||||
void setWidget(QWidget *widget);
|
||||
};
|
||||
|
||||
#endif // FRAMELESSWIDGET_H
|
||||
23
framelesswidget/framelesswidget.pro
Normal file
23
framelesswidget/framelesswidget.pro
Normal file
@@ -0,0 +1,23 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2019-10-03T10:55:58
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = framelesswidget
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmframelesswidget.cpp
|
||||
SOURCES += framelesswidget.cpp
|
||||
|
||||
HEADERS += frmframelesswidget.h
|
||||
HEADERS += framelesswidget.h
|
||||
|
||||
FORMS += frmframelesswidget.ui
|
||||
38
framelesswidget/frmframelesswidget.cpp
Normal file
38
framelesswidget/frmframelesswidget.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmframelesswidget.h"
|
||||
#include "ui_frmframelesswidget.h"
|
||||
#include "qpushbutton.h"
|
||||
#include "framelesswidget.h"
|
||||
|
||||
frmFramelessWidget::frmFramelessWidget(QWidget *parent) : QWidget(parent), ui(new Ui::frmFramelessWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
frmFramelessWidget::~frmFramelessWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmFramelessWidget::on_btnOpen_clicked()
|
||||
{
|
||||
QWidget *w = new QWidget;
|
||||
w->setAttribute(Qt::WA_DeleteOnClose);
|
||||
w->setWindowTitle("自由拉伸无边框窗体");
|
||||
w->resize(480, 320);
|
||||
|
||||
//设置下背景颜色区别看
|
||||
QPalette palette = w->palette();
|
||||
palette.setBrush(QPalette::Background, QColor(162, 121, 197));
|
||||
w->setPalette(palette);
|
||||
|
||||
QPushButton *btn = new QPushButton(w);
|
||||
connect(btn, SIGNAL(clicked(bool)), w, SLOT(close()));
|
||||
btn->setGeometry(10, 10, 100, 25);
|
||||
btn->setText("关闭");
|
||||
|
||||
FramelessWidget *f = new FramelessWidget(w);
|
||||
f->setWidget(w);
|
||||
w->show();
|
||||
}
|
||||
26
framelesswidget/frmframelesswidget.h
Normal file
26
framelesswidget/frmframelesswidget.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef FRMFRAMELESSWIDGET_H
|
||||
#define FRMFRAMELESSWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class frmFramelessWidget;
|
||||
}
|
||||
|
||||
class frmFramelessWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmFramelessWidget(QWidget *parent = 0);
|
||||
~frmFramelessWidget();
|
||||
|
||||
private:
|
||||
Ui::frmFramelessWidget *ui;
|
||||
|
||||
private slots:
|
||||
void on_btnOpen_clicked();
|
||||
};
|
||||
|
||||
#endif // FRMFRAMELESSWIDGET_H
|
||||
32
framelesswidget/frmframelesswidget.ui
Normal file
32
framelesswidget/frmframelesswidget.ui
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmFramelessWidget</class>
|
||||
<widget class="QWidget" name="frmFramelessWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QPushButton" name="btnOpen">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>181</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>弹窗无边框窗体</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
31
framelesswidget/main.cpp
Normal file
31
framelesswidget/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmframelesswidget.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmFramelessWidget w;
|
||||
w.setWindowTitle("无边框窗体类");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
Reference in New Issue
Block a user