这里要做两个处理:1.widget的上浮和下层 2.widget的伸缩动画。
上浮和下层可以通过设置widget的属性来控制:
if(isfloating)
{
m_is_floating = true;
setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip);
}
else
{
m_is_floating = false;
setWindowFlags(Qt::FramelessWindowHint | Qt::Widget);
Qt::WindowFlags:
那么就要好好说说控件的窗口标识的设置了。窗口标识由两部分组成分别是窗口类型和窗口提示hint,一个窗口只有一个窗口类型。窗口提示定义了窗口的外观,可以有多个提示,窗口提示进行按位取或即可。
要说清楚Qt::WindowFlags枚举类型就必须清楚两个概念:窗口和部件(这样划分便于区分)
窗口:相对独立的,有子窗口和父窗口之分,主要特点就是窗口有完整的边框,把没有嵌入到其他部件中的部件称为窗口,一般的窗口都有边框和标题栏。
部件:必须依赖于父窗口而存在,依赖性较强,出现在父窗体的界面内部,它们嵌入在别的窗口中。
有了上述的概念就好解释Qt::WindowFlags枚举类型的用法了。首先判断一个控件是否是窗体先根据参数parent的指定,要是值为0那么就可以判断其是一个窗口。否则需要根据Qt::WindowFlags枚举类型的值才可以判断其是否为窗口还是部件。
下面是翻译的官方文档的解释,然鹅并不是很清除;
Qt::Widget 0x00000000 这是QWidget的默认类型。这种类型的窗口小部件是子窗口小部件(如果它们有父窗口),独立窗口(如果它们没有父窗口)。参见Qt::Window和Qt::SubWindow。
Qt::Window 0x00000001 表示小部件是一个窗口,通常带有一个窗口系统框架和一个标题栏,不管小部件是否有父窗口。注意,如果小部件没有父组件,则不可能取消设置此标志。
Qt::Dialog 0x00000002 窗口表示小部件是一个应该装饰为对话框的窗口(即,通常标题栏中没有最大化或最小化按钮)。这是QDialog的默认类型。如果您想使用它作为一个模态对话框,则应该从另一个窗口启动它,或者有一个父窗口并与QWidget::windowModality属性一起使用。如果将其设置为模态,则对话框将阻止应用程序中的其他顶级窗口获得任何输入。我们将具有父窗口的顶级窗口称为辅助窗口。
Qt::Sheet 0x00000004 窗口表示该窗口是Macintosh工作表。由于使用工作表意味着窗口模式,建议使用QWidget::setWindowModality()或QDialog::open()。
Qt::Drawer 0x00000006 窗口表示小部件是Macintosh的drawer。
Qt::Popup 0x00000008 窗口表示小部件是一个弹出的顶级窗口,即它是模态的,但是有一个适合弹出菜单的窗口系统框架。
Qt::Tool 0x0000000a 窗口表示小部件是一个工具窗口。工具窗口通常是一个比通常标题栏和装饰小的窗口,通常用于工具按钮的集合。如果有父类,工具窗口将始终保持在它的顶部。如果没有父类,也可以考虑使用Qt::WindowStaysOnTopHint。如果窗口系统支持它,工具窗口可以用稍微轻一些的框架装饰。它还可以与Qt::FramelessWindowHint相结合。
在Mac OS X上,工具窗口对应于窗口的浮动类。这意味着窗口位于正常窗口之上的一层;在它上面放一个普通的窗户是不可能的。默认情况下,当应用程序处于非活动状态时,工具窗口将会消失。这可以由Qt::WA_MacAlwaysShowToolWindow属性控制。
Qt::ToolTip 0x0000000c 窗口表示小部件是一个工具提示。这在内部用于实现工具提示。
Qt::SplashScreen 0x0000000e 窗口表示该窗口是一个闪屏。这是QSplashScreen的默认类型。
Qt::Desktop 0x00000010 窗口表示这个小部件就是桌面。这是QDesktopWidget的类型。
Qt::SubWindow 0x00000012表示此小部件是子窗口,例如QMdiSubWindow小部件。
看这个吧:
Qt::Widget //是一个窗口或部件,有父窗口就是部件,没有就是窗口
Qt::Window //是一个窗口,有窗口边框和标题
Qt::Dialog //是一个对话框窗口
Qt::Sheet //是一个窗口或部件Macintosh表单
Qt::Drawer //是一个窗口或部件Macintosh抽屉
Qt::Popup //是一个弹出式顶层窗口
Qt::Tool //是一个工具窗口
Qt::ToolTip //是一个提示窗口,没有标题栏和窗口边框
Qt::SplashScreen //是一个欢迎窗口,是QSplashScreen构造函数的默认值
Qt::Desktop //是一个桌面窗口或部件
Qt::SubWindow //是一个子窗口 //为窗口添加一些功能
Qt::CustomizeWindowHint //关闭默认窗口标题提示
Qt::WindowTitleHint //为窗口修饰一个标题栏
Qt::WindowSystemMenuHint //为窗口修饰一个窗口菜单系统
Qt::WindowMinimizeButtonHint //为窗口添加最小化按钮
Qt::WindowMaximizeButtonHint //为窗口添加最大化按钮
Qt::WindowMinMaxButtonsHint //为窗口添加最大化和最小化按钮
Qt::WindowCloseButtonHint
Qt::WindowContextHelpButtonHint
Qt::MacWindowToolBarButtonHint
Qt::WindowFullscreenButtonHint
Qt::BypassGraphicsProxyWidgetQt::WindowShadeButtonHint
Qt::WindowStaysOnTopHintQt::WindowStaysOnBottomHint
Qt::WindowOkButtonHintQt::WindowCancelButtonHint
Qt::WindowTransparentForInput
关于WindowFlags就到这,下面介绍伸缩效果:
主要是用过QT的QPropertyAnimation 属性(动画效果的实质就是用过定时器将一个变化动作进行插值,显示过程).
这里变换的动动作是Widget的高
Q_PROPERTY(int flexhight READ flexhight WRITE setflexhight)//增加一个高的属性
animation = new QPropertyAnimation(this, "flexhight"); //初始化动画类
animation->setDuration(50); //设置变换速度(50)
animation->setEasingCurve(QEasingCurve::InQuad);(这里我理解为变换的加速度类型(先快后慢)
源码如下:
widget.h
#ifndef ADAPTER_WIDGET_H
#define ADAPTER_WIDGET_H
#include <QPropertyAnimation>
#include <QPushButton>
#include <QPainter>
#include <QColor>
#include <QBrush>
#include <QLayout>
#include <QWidget>
class QStackedWidget;
class PushButton;
class AdapterWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(int flexhight READ flexhight WRITE setflexhight)
public:
explicit AdapterWidget(QWidget *parent = 0);
~AdapterWidget();
int flexhight()
{
return this->height();
}
void setflexhight(int heigh)
{
setFixedHeight(heigh);
}
void addWidget(QWidget *);
void setCurrentIndex(int);
void set_stretch();
void set_shrink();
bool status();
bool is_floating();
void set_floating(bool);
signals:
void signal_adapter_floating(bool);
public slots:
void slot_amotion();
void slot_floating_click();
private:
QPropertyAnimation *animation;
QStackedWidget *m_stackewidget;
bool m_is_floating;
PushButton *m_floating_button;
};
#endif // ADAPTER_WIDGET_H
widget.cc
#include "adapter_widget.h"
#include <QStackedWidget>
#include <QHBoxLayout>
#include "defwidgets/pushbutton.h"
AdapterWidget::AdapterWidget(QWidget *parent):
QWidget(parent),
m_is_floating(false)
{
setParent(parent);
m_stackewidget = new QStackedWidget(this);
m_floating_button = new PushButton("float" ,this);
setFixedHeight(51);
setWindowFlags(Qt::FramelessWindowHint);
animation = new QPropertyAnimation(this, "flexhight");
animation->setDuration(50);
animation->setEasingCurve(QEasingCurve::InQuad);
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->setSpacing(0);
hlayout->setContentsMargins(0, 0, 0, 0);
hlayout->addWidget(m_stackewidget);
hlayout->addWidget(m_floating_button);
hlayout->setStretch(0, 20);
hlayout->setStretch(1, 1);
setLayout(hlayout);
connect(m_floating_button, SIGNAL(clicked()), this, SLOT(slot_floating_click()));
}
AdapterWidget::~AdapterWidget()
{
}
void AdapterWidget::addWidget(QWidget *widget)
{
m_stackewidget->addWidget(widget);
}
void AdapterWidget::setCurrentIndex(int index)
{
m_stackewidget->setCurrentIndex(index);
}
void AdapterWidget::set_stretch()
{
}
void AdapterWidget::set_shrink()
{
}
bool AdapterWidget::status()
{
return height() > 50 ? true : false;
}
bool AdapterWidget::is_floating()
{
return m_is_floating;
}
void AdapterWidget::set_floating(bool isfloating)
{
if(isfloating)
{
m_is_floating = true;
setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip);
}
else
{
m_is_floating = false;
setWindowFlags(Qt::FramelessWindowHint | Qt::Widget);
}
}
void AdapterWidget::slot_amotion()
{
if (height() > 50)
{
animation->setEndValue(0);
}
else
{
animation->setEndValue(51);
}
animation->start();
}
void AdapterWidget::slot_floating_click()
{
if(m_is_floating)
{
set_floating(false);
}
else
{
set_floating(true);
}
emit signal_adapter_floating(m_is_floating);
}
代码源码地址:https://download.csdn.net/download/mario_z/11224710