仿照word的界面的滑动菜单(2)(伸缩下拉框)

这里要做两个处理: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 
#include 
#include 
#include 
#include 
#include 
#include 

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 
#include 
#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

 

你可能感兴趣的:(Qt控件系列)