当您在Mac上保存文件时,面板会以非常酷的方式从顶部栏向下下降.我想创建一个使用Qt框架执行类似操作的类.我有很多困惑:
面板下降时,应阻止输入父窗口.使用QDialog很容易,因为它有setModal()方法,但是QDialogs默认弹出.我不知道怎么解决这个问题.
在QMainProject中,创建了DescendingPanel类的QMenua新实例.假设菜单栏下面还有其他小部件,你会怎么做?DescendingPanel应出现在它们上方.
我真的很感激任何帮助.
编辑
我有一个想法,而不是在菜单栏下挂下对话框,只是让它出现在那里并移除窗框.这样,它就会产生一种幻觉,它从那里弹出.当然,还必须处理Move事件,以便Dialog始终位于菜单栏下,但这是为了以后.这是我用来让DescendingDialog出现在菜单栏下面的代码.
class DescendingDialog : public QWidget
{
QMainWindow* Window;
QWidget* Menu;
QPoint GlobalLocationOfMenu;
int DialogWidth;
int DialogHeight;
int X()
{
int XDistanceOfPanel = GlobalLocationOfMenu.x() + ((Menu->width()/2) - (this->DialogWidth/2));
//GlobalLocationOfMenu.x() returns 0;
return XDistanceOfPanel;
}
int Y()
{
int YDistanceOfPanel = GlobalLocationOfMenu.y()+Menu->height();
//GlobalLocationOfMenu.y() returns 0;
return YDistanceOfPanel;
}
void SetGeometry()
{
this->setGeometry(this->X(),this->Y(),this->DialogWidth,this->DialogHeight);
}
public:
DescendingDialog(QMainWindow* Window,int DialogWidth,int DialogHeight):QWidget(NULL)
{
this->Window = Window;
this->Menu = this->Window->menuWidget();
this->DialogWidth = DialogWidth;
this->DialogHeight = DialogHeight;
QPoint RelativeLocationOfMenu = this->Menu->pos();
this->GlobalLocationOfMenu = QWidget::mapToGlobal(RelativeLocationOfMenu);
this->SetGeometry();
}
};
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为GlobalLocationOfMenu.x()和.y()返回0,因此对话框不会出现在我想要的位置.
您可以使用类似于以下的函数让对话框“滑入”:
#include <QDialog>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>
void makeAppear(QDialog * dialog, QRect geometryEnd)
{
static QParallelAnimationGroup *animationGroup = 0;
if (animationGroup)
{
for(int i = 0, ie = animationGroup->animationCount(); i != ie; ++i)
delete animationGroup->animationAt(i);
delete animationGroup;
}
// Set up start and end geometry for 'dialog'.
QPoint parentTopLeft = dialog->parentWidget()->geometry().topLeft();
geometryEnd.translate(dialog->parentWidget()->mapToGlobal(parentTopLeft));
QRect geometryBegin = geometryEnd;
geometryBegin.setHeight(0);
// Set up start and end geometry for the only child widget of 'dialog'.
QWidget * dialogChildWidget = dynamic_cast< QWidget * >(dialog->children().first());
if ( !dialogChildWidget )
return;
QRect childGeometryEnd = dialogChildWidget->geometry();
QRect childGeometryBegin = childGeometryEnd;
childGeometryBegin.translate(0, geometryEnd.height() * (-1));
// Set up animation for 'dialog'.
QPropertyAnimation *dialogAnimation = new QPropertyAnimation(dialog, "geometry");
dialogAnimation->setDuration(400);
dialogAnimation->setStartValue(geometryBegin);
dialogAnimation->setEndValue(geometryEnd);
// Set up animation for the only child widget of 'dialog'.
QPropertyAnimation *childAnimation = new QPropertyAnimation(dialogChildWidget, "geometry");
childAnimation->setDuration(400);
childAnimation->setStartValue(childGeometryBegin);
childAnimation->setEndValue(childGeometryEnd);
// Set up (and start) a parallel animation group
animationGroup = new QParallelAnimationGroup;
animationGroup->addAnimation(dialogAnimation);
animationGroup->addAnimation(childAnimation);
animationGroup->start();
// Make 'dialog' visible, borderless, modal.
dialog->setModal(true);
dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
dialog->show();
}
Run Code Online (Sandbox Code Playgroud)
该dialog参数应指向一个(隐藏/不可见)QDialog 实例,该实例具有一个子窗口小部件,该子窗口小部件包含属于该对话框的所有其他窗口小部件。
该geometryEnd参数应指定其出现后的位置和大小dialog(相对于其父窗口小部件)。
结果看起来像这样。