1
0
mirror of https://gitee.com/drabel/LibQQt.git synced 2025-01-04 10:18:44 +08:00

add framelesshelper

This commit is contained in:
tianduanrui 2017-10-21 21:55:12 +08:00
parent e6c88792c5
commit 1a936f389a
12 changed files with 819 additions and 36 deletions

View File

@ -1,7 +1,8 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += src/qqt.pro
SUBDIRS += src/qqt.pro \
examples/framelesshelperwidget
#SUBDIRS += examples/qqtframe
SUBDIRS += examples/qqtframe2
#SUBDIRS += examples/animationframe

View File

@ -13,39 +13,37 @@
<property name="windowTitle">
<string>QQtExquisiteForm</string>
</property>
<widget class="QQtCustomSpeedMeter" name="w0" native="true">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>241</width>
<height>251</height>
</rect>
</property>
</widget>
<widget class="QQtCustomProgressBar" name="w2" native="true">
<property name="geometry">
<rect>
<x>300</x>
<y>30</y>
<width>251</width>
<height>251</height>
</rect>
</property>
</widget>
<widget class="QSlider" name="hs0">
<property name="geometry">
<rect>
<x>40</x>
<y>380</y>
<width>501</width>
<height>22</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QQtCustomSpeedMeter" name="w0" native="true"/>
</item>
<item row="0" column="1">
<widget class="QQtCustomProgressBar" name="w2" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
</item>
<item>
<widget class="QSlider" name="hs0">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -0,0 +1,88 @@
#-------------------------------------------------
#
# Project created by QtCreator 2017-10-21T21:26:55
#
#-------------------------------------------------
#include QQt's header (add QQt header to includepath)
include(../../src/qqt_header.pri)
#CONFIG += BUILD_SRC
contains (CONFIG, BUILD_SRC) {
#if you want to build src but not link QQt in this project
#include(../../src/qqt.pri)
} else {
#if you want to link QQt library
message(Link QQt to $${TARGET} $${QKIT_} from $${SYSNAME} $${BUILD} on $${QMAKE_HOST.os})
equals(QMAKE_HOST.os, Darwin) {
equals(QKIT_, macOS) {
LIBS += -F/Users/abel/Develop/c0-buildstation/a0-qqtfoundation/$${SYSNAME}/$${BUILD}/src/bin
LIBS += -framework QQt
} else: equals(QKIT_, Android) {
LIBS += -L/Users/abel/Develop/c0-buildstation/a0-qqtfoundation/$${SYSNAME}/$${BUILD}/src/bin
LIBS += -lQQt
} else: equals(QKIT_, ANDROIDX86) {
LIBS += -L/Users/abel/Develop/c0-buildstation/a0-qqtfoundation/$${SYSNAME}/$${BUILD}/src/bin
LIBS += -lQQt
}
} else: equals(QMAKE_HOST.os, Linux) {
LIBS += -L/home/abel/Develop/c0-buildstation/a0-qqtfoundation/$${SYSNAME}/$${BUILD}/src/bin
LIBS += -lQQt
} else: equals(QMAKE_HOST.os, Windows) {
LIBS += -LC:/Users/Administrator/Develop/c0-build/a0-qqtfoundation/$${SYSNAME}/$${BUILD}/src/bin
LIBS += -lQQt
}
}
############
##install
############
#CONFIG += can_install
can_install:equals(QKIT_, MIPS32) {
target.path = /Application
INSTALLS += target
} else: unix {
equals(QKIT_, macOS) {
target.path = /Applications
INSTALLS += target
}
}
equals(QKIT_, macOS) {
CONFIG += app_bundle
}
equals(QKIT_, Android) {
CONFIG += mobility
MOBILITY =
#DISTFILES += \
# android/AndroidManifest.xml
#ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
}
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = framelesshelperwidget
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui

View File

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

View File

@ -0,0 +1,23 @@
#include "widget.h"
#include "ui_widget.h"
#include "qqtframelesshelper.h"
Widget::Widget(QWidget* parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QQtFramelessHelper* frameless = new QQtFramelessHelper(this);
frameless->addDragWidget(this);
frameless->setCloseButton(ui->pushButtonClose);
frameless->setMaximizedButton(ui->pushButtonMax);
frameless->setRestoreButton(ui->pushButtonRestore);
frameless->setMinimizedButton(ui->pushButtonMin, false);
}
Widget::~Widget()
{
delete ui;
}

View File

@ -0,0 +1,22 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButtonMin">
<property name="text">
<string>最小化</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonMax">
<property name="text">
<string>最大化</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonRestore">
<property name="text">
<string>还原</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonClose">
<property name="text">
<string>关闭</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>266</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,95 @@
//#include "stdafx.h"
#include "qqtframelesshelper.h"
#include "qqtframelesshelperprivate.h"
#include <QWidget>
#include <QPushButton>
#include <QDebug>
QQtFramelessHelper::QQtFramelessHelper(QWidget* parent) : QObject(parent)
{
d = new QQtFramelessHelperPrivate(parent);
}
void QQtFramelessHelper::setResizeMargins(int margin)
{
setResizeMargins(QMargins(margin, margin, margin, margin));
}
void QQtFramelessHelper::setResizeMargins(const QMargins& margins)
{
d->margins = margins;
}
void QQtFramelessHelper::setCloseButton(QPushButton* button, bool edgeResize)
{
d->buttonClose = button;
connect(d->buttonClose, SIGNAL(clicked(bool)),
d->parent, SLOT(close()));
if (edgeResize)
{
d->addEdgeWidget(button);
}
}
void QQtFramelessHelper::setMaximizedButton(QPushButton* button, bool edgeResize)
{
d->buttonMaximized = button;
connect(d->buttonMaximized, SIGNAL(clicked(bool)),
d->parent, SLOT(showMaximized()));
if (edgeResize)
{
d->addEdgeWidget(button);
}
d->refreshMaximizedButton();
}
void QQtFramelessHelper::setMinimizedButton(QPushButton* button, bool edgeResize)
{
d->buttonMinimized = button;
connect(d->buttonMinimized, SIGNAL(clicked(bool)),
d->parent, SLOT(showMinimized()));
if (edgeResize)
{
d->addEdgeWidget(button);
}
}
void QQtFramelessHelper::setRestoreButton(QPushButton* button, bool edgeResize)
{
d->buttonRestore = button;
connect(d->buttonRestore, SIGNAL(clicked(bool)),
d->parent, SLOT(showNormal()));
if (edgeResize)
{
d->addEdgeWidget(button);
}
d->refreshMaximizedButton();
}
void QQtFramelessHelper::addEdgeWidget(QWidget* widget)
{
d->addEdgeWidget(widget);
}
void QQtFramelessHelper::addDragWidget(QWidget* widget)
{
d->addDragWidget(widget);
}

View File

@ -0,0 +1,37 @@
#ifndef QQTFRAMELESSHELPER_H
#define QQTFRAMELESSHELPER_H
/**
* T.D.R (QQ:2657635903) mod 2017102121:24:43
**/
#include <QObject>
#include <QMargins>
class QPushButton;
class QWidget;
class QQtFramelessHelperPrivate;
class QQtFramelessHelper : public QObject
{
Q_OBJECT
public:
explicit QQtFramelessHelper(QWidget* parent);
void setResizeMargins(int margin);
void setResizeMargins(const QMargins& margins);
void setCloseButton(QPushButton* button, bool edgeResize = true);
void setMaximizedButton(QPushButton* button, bool edgeResize = true);
void setMinimizedButton(QPushButton* button, bool edgeResize = true);
void setRestoreButton(QPushButton* button, bool edgeResize = true);
void addEdgeWidget(QWidget* widget);
void addDragWidget(QWidget* widget);
private:
QQtFramelessHelperPrivate* d;
};
#endif // QQTFRAMELESSHELPER_H

View File

@ -0,0 +1,337 @@
#include "qqtframelesshelperprivate.h"
#include <QTimer>
#include <QWidget>
#include <QMouseEvent>
#include <QPushButton>
#include <QDebug>
#include <QApplication>
QQtFramelessHelperPrivate::QQtFramelessHelperPrivate(QWidget* parent)
: parent(parent),
isMaximized(false),
direction(None),
buttonMaximized(0),
buttonRestore(0),
buttonClose(0),
buttonMinimized(0),
isMousePressed(false),
QObject(parent)
{
margins = QMargins(5, 5, 5, 5);
parent->setWindowFlags(parent->windowFlags() | (Qt::FramelessWindowHint));
parent->installEventFilter(this);
timer = new QTimer(this);
timer->setInterval(400);
connect(timer, SIGNAL(timeout()), this, SLOT(checkPos()));
timer->start();
}
void QQtFramelessHelperPrivate::addEdgeWidget(QWidget* widget)
{
if (!edgeWidgets.contains(widget))
{
edgeWidgets.append(widget);
if (!dragWidgets.contains(widget))
{
widget->installEventFilter(this);
}
}
}
void QQtFramelessHelperPrivate::addDragWidget(QWidget* widget)
{
if (!dragWidgets.contains(widget))
{
dragWidgets.append(widget);
if (!edgeWidgets.contains(widget))
{
widget->installEventFilter(this);
}
}
}
void QQtFramelessHelperPrivate::checkPos()
{
QRect rectMustIn = parent->frameGeometry();
QRect rectMustNotIn = rectMustIn.marginsRemoved(margins);
QPoint cursorPos = QCursor::pos();
if (isMaximized ||
!parent->isActiveWindow() ||
!rectMustIn.contains(cursorPos) ||
rectMustNotIn.contains(cursorPos))
{
direction = None;
parent->unsetCursor();
return;
}
int baseLeftCoord, baseTopCoord, baseRightCoord, baseBottomCoord;
rectMustNotIn.getCoords(&baseLeftCoord, &baseTopCoord, &baseRightCoord, &baseBottomCoord);
int x, y;
x = cursorPos.x();
y = cursorPos.y();
direction = None;
if (x < baseLeftCoord)
{
if (y < baseTopCoord)
{
direction = LeftTop;
}
else if (y > baseBottomCoord)
{
direction = LeftBottom;
}
else
{
direction = Left;
}
}
else if (x > baseRightCoord)
{
if (y < baseTopCoord)
{
direction = RightTop;
}
else if (y > baseBottomCoord)
{
direction = RightBottom;
}
else
{
direction = Right;
}
}
if (direction == None)
{
if (y < baseTopCoord)
{
direction = Top;
}
else
{
direction = Bottom;
}
}
switch (direction)
{
case Left:
case Right:
parent->setCursor(Qt::SizeHorCursor);
break;
case Top:
case Bottom:
parent->setCursor(Qt::SizeVerCursor);
break;
case LeftTop:
case RightBottom:
parent->setCursor(Qt::SizeFDiagCursor);
break;
case LeftBottom:
case RightTop:
parent->setCursor(Qt::SizeBDiagCursor);
break;
}
}
void QQtFramelessHelperPrivate::resize(const QPoint& cursorPos)
{
QSize oldSize = parent->size();
int x, y, width = 0, height = 0;
switch (direction)
{
case Left: // left
width = oldSize.width() - cursorPos.x();
height = oldSize.height();
x = parent->pos().x() - (width - oldSize.width());
y = parent->pos().y();
break;
case Right: //right
width = cursorPos.x();
height = oldSize.height();
x = parent->pos().x();
y = parent->pos().y();
break;
case LeftTop: //left top
width = oldSize.width() - cursorPos.x();
height = oldSize.height() - cursorPos.y();
x = parent->pos().x() - (width - oldSize.width());
y = parent->pos().y() - (height - oldSize.height());
break;
case RightTop: //right top
width = cursorPos.x();
height = oldSize.height() - cursorPos.y();
x = parent->pos().x();
y = parent->pos().y() - (height - oldSize.height());
break;
case LeftBottom: //left bottom
width = oldSize.width() - cursorPos.x();
height = cursorPos.y();
x = parent->pos().x() - (width - oldSize.width());
y = parent->pos().y();
break;
case RightBottom: //right bottom
width = cursorPos.x();
height = cursorPos.y();
x = parent->pos().x();
y = parent->pos().y();
break;
case Top: //top
width = oldSize.width();
height = oldSize.height() - cursorPos.y();
x = parent->pos().x();
y = parent->pos().y() - (height - oldSize.height());
break;
case Bottom: //bottom
width = oldSize.width();
height = cursorPos.y();
x = parent->pos().x();
y = parent->pos().y();
break;
}
if (width > (margins.left() + margins.right()) &&
height > (margins.top() + margins.bottom()))
{
parent->move(x, y);
parent->resize(width, height);
}
}
void QQtFramelessHelperPrivate::refreshMaximizedButton()
{
isMaximized = parent->windowState().testFlag(Qt::WindowMaximized);
if (buttonRestore != 0)
{
buttonRestore->setVisible(isMaximized);
}
if (buttonMaximized != 0)
{
buttonMaximized->setVisible(!isMaximized);
}
}
bool QQtFramelessHelperPrivate::eventFilter(QObject* obj, QEvent* event)
{
do
{
if (event->type() == QEvent::WindowStateChange)
{
refreshMaximizedButton();
break;
}
if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* e = (QMouseEvent*)event;
// no move, no drag
if (e->button() != Qt::LeftButton || isMaximized)
{
break;
}
checkPos();
if ((obj == parent || edgeWidgets.contains(qobject_cast<QWidget*>(obj))) && direction != None)
{
isMousePressed = true;
operation = MoveResize;
timer->stop();
return true;
}
if (dragWidgets.contains(qobject_cast<QWidget*>(obj)) && direction == None)
{
isMousePressed = true;
operation = MoveDrag;
dragBasePoint = e->globalPos() - parent->pos();
timer->stop();
return true;
}
break;
}
if (event->type() == QEvent::MouseMove && isMousePressed)
{
QMouseEvent* e = (QMouseEvent*)event;
if (operation == MoveDrag)
{
parent->move(e->globalPos() - dragBasePoint);
return true;
}
if (operation == MoveResize)
{
if (obj != parent)
{
QWidget* w = qobject_cast<QWidget*>(obj);
resize(w->mapTo(parent, e->pos()));
}
else
{
resize(e->pos());
}
return true;
}
break;
}
if (event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* e = (QMouseEvent*)event;
if (e->button() == Qt::LeftButton && isMousePressed)
{
isMousePressed = false;
operation = MoveNone;
timer->start();
return true;
}
break;
}
}
while (false);
return QObject::eventFilter(obj, event);
}

View File

@ -0,0 +1,75 @@
#ifndef QQTFRAMELESSHELPERPRIVATE_H
#define QQTFRAMELESSHELPERPRIVATE_H
#include <QObject>
#include <QPoint>
#include <QMargins>
class QPushButton;
class QWidget;
class QEvent;
class QTimer;
class QMouseEvent;
class QQtFramelessHelperPrivate : public QObject
{
Q_OBJECT
public:
QPushButton* buttonMaximized;
QPushButton* buttonRestore;
QPushButton* buttonClose;
QPushButton* buttonMinimized;
QList<QWidget*> dragWidgets;
QList<QWidget*> edgeWidgets;
QWidget* parent;
QMargins margins;
QQtFramelessHelperPrivate(QWidget* parent);
void addEdgeWidget(QWidget* widget);
void addDragWidget(QWidget* widget);
void refreshMaximizedButton();
protected:
enum MoveDirection
{
None = 0,
Left,
Right,
LeftTop,
RightTop,
LeftBottom,
RightBottom,
Top,
Bottom,
};
enum MoveOperation
{
MoveNone = 0,
MoveResize,
MoveDrag,
};
protected:
bool eventFilter(QObject* obj, QEvent* event);
private slots:
void checkPos();
void resize(const QPoint& cursorPos);
private:
bool isMaximized;
MoveDirection direction;
MoveOperation operation;
bool isMousePressed;
QTimer* timer;
QPoint dragBasePoint;
};
#endif // QQTFRAMELESSHELPERPRIVATE_H

View File

@ -28,12 +28,16 @@ SOURCES = \
$$PWD/exquisite/qqtcustomprogressbar.cpp \
$$PWD/exquisite/qqtcustomspeedmeter.cpp \
$$PWD/exquisite/qqtcustomsliderruler.cpp \
$$PWD/exquisite/qqtcustompiano.cpp
$$PWD/exquisite/qqtcustompiano.cpp \
$$PWD/exquisite/qqtframelesshelper.cpp \
$$PWD/exquisite/qqtframelesshelperprivate.cpp
HEADERS = \
$$PWD/exquisite/qqtcustomprogressbar.h \
$$PWD/exquisite/qqtcustomspeedmeter.h \
$$PWD/exquisite/qqtcustomsliderruler.h \
$$PWD/exquisite/qqtcustompiano.h
$$PWD/exquisite/qqtcustompiano.h \
$$PWD/exquisite/qqtframelesshelper.h \
$$PWD/exquisite/qqtframelesshelperprivate.h
#root dir
win32 {