2011-12-18 26 views
6

Khi bạn lưu tệp trên máy Mac, một loại bảng điều khiển sẽ hạ xuống từ thanh trên cùng một cách thực sự tuyệt vời. Tôi muốn tạo một lớp làm một điều tương tự bằng cách sử dụng khung công tác Qt. Có một số điều mà tôi đang bối rối về:Cách đính kèm 'bảng điều khiển giảm dần' xuống dưới cùng của Thanh menu trong QMainWindow

  1. Khi bảng điều khiển xuống, nhập vào cửa sổ chính nên bị chặn. Điều này rất dễ dàng với QDialog vì nó có phương thức setModal(), tuy nhiên - QDialogs, theo mặc định là pop-out. Tôi không chắc chắn làm thế nào để có được xung quanh này.

  2. Trong QMainProject, có một phiên bản QMenua mới của lớp DescendingPanel được tạo. Làm thế nào bạn sẽ làm điều đó, giả sử có các vật dụng khác bên dưới thanh thực đơn. DescendingPanel sẽ xuất hiện phía trên chúng.

Tôi thực sự đánh giá cao bất kỳ trợ giúp nào về điều này.

EDIT

Tôi đã có một ý kiến ​​cho rằng thay vì pegging hộp thoại dưới thanh menu, chỉ cần làm cho nó xuất hiện dưới đó và loại bỏ các khung cửa sổ. Bằng cách đó, nó sẽ tạo ra một ảo giác rằng nó xuất hiện từ dưới đó. Ofcourse, Di chuyển các sự kiện cũng sẽ phải được xử lý để hộp thoại luôn luôn dưới menubar nhưng đó là cho sau này. Đây là mã tôi sử dụng để có được DescendingDialog xuất hiện dưới thanh thực đơn.

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(); 

    } 
}; 

Nó không hoạt động vì GlobalLocationOfMenu.x() và .y() trả lại 0 để hộp thoại không xuất hiện ở nơi tôi muốn.

+0

Tôi vừa có ý tưởng. Thay vì gắn hộp thoại vào dưới cùng của thanh công cụ QToolbar, tôi có thể cố gắng đặt tọa độ theo cách tương đối sao cho bảng điều khiển luôn xuất hiện bên dưới thanh công cụ ngay cả khi QMainMindow được di chuyển xung quanh màn hình. Tôi sẽ xem tôi có thể thực hiện điều đó không. Nếu nó hoạt động, thì tất cả những gì còn lại sẽ là loại bỏ Glass-Frame (cái có chứa các nút phóng to, thu nhỏ và đóng) - loại bỏ chúng sẽ ngụy trang thực tế là hộp thoại nằm trong cửa sổ riêng biệt. –

+0

Tôi đã thử làm như trên, nhưng tôi không thể để Hộp thoại xuất hiện ngay bên dưới Thanh công cụ. Tôi đã có vị trí của thanh công cụ bằng cách sử dụng pos() và thiết lập vị trí của hộp thoại liên quan đến thanh công cụ, nhưng nó xuất hiện ngoài trung tâm trong hầu hết các trường hợp. –

+0

bạn có sử dụng phương pháp mapToGlobal không? hãy nhớ rằng pos sẽ trở lại tương đối với vị trí cha –

Trả lời

2

Bạn có thể để một hộp thoại "slide trong" bằng cách sử dụng một chức năng tương tự như:

#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(); 
} 

Đối số dialog sẽ trỏ đến một (ẩn/không nhìn thấy được) QDialog dụ với một tiện ích con duy nhất, mà chứa tất cả các tiện ích khác thuộc về hộp thoại.

Đối số geometryEnd phải chỉ định vị trí và kích thước của dialog sau khi nó xuất hiện (tương ứng với tiện ích con của phụ huynh).

Kết quả trông like this.

+0

+ 50! Cám ơn rất nhiều! Tôi có hiệu ứng tôi muốn và tôi có thể làm việc thực sự xây dựng từ điều này. Thực sự rõ ràng. Cảm ơn một lần nữa :) –

Các vấn đề liên quan