2015-07-28 20 views
5

Piszę menu podręczne dla widżetu przycisku Qt, po kliknięciu przycisku, wyskakujące menu (pod przyciskiem).Ustaw pozycję (w prawo) menu kontekstowego Qt PushButton

Domyślnie wyskakujące menu jest lewostronne. Czy są jakieś sposoby, aby wyskakujące menu pojawiło się po prawej stronie pod przyciskiem?

Nie ma ustawionej funkcji pozycji ... więc zastanawiam się, czy jest jakiś wyrafinowany sposób robienia tego?

Oto niektóre kodu (do menu podręcznego):

QMenu *menuMode = new QMenu(this); 
    min = menu ->addAction("In"); 
    mout = menu ->addAction("out"); 
ui->pushButtonMode->setMenu(menuMode); //I am writing in MainWindow, that's there is ui 

Dziękuję bardzo za wszelkie wskazówki i porady.

Odpowiedz

5

Można to zrobić przez instacji QMenu i przesuwając menu kontekstowe, w którym chcesz mieć go w showEvent:

popupmenu.h

#ifndef POPUPMENU_H 
#define POPUPMENU_H 

#include <QMenu> 

class QPushButton; 
class QWidget; 

class PopupMenu : public QMenu 
{ 
    Q_OBJECT 
public: 
    explicit PopupMenu(QPushButton* button, QWidget* parent = 0); 
    void showEvent(QShowEvent* event); 
private: 
    QPushButton* b; 
}; 

#endif // POPUPMENU_H 

popupmenu.cpp

#include "popupmenu.h" 
#include <QPushButton> 

PopupMenu::PopupMenu(QPushButton* button, QWidget* parent) : QMenu(parent), b(button) 
{ 
} 

void PopupMenu::showEvent(QShowEvent* event) 
{ 
    QPoint p = this->pos(); 
    QRect geo = b->geometry(); 
    this->move(p.x()+geo.width()-this->geometry().width(), p.y()); 
} 

mainwindow.cpp

... 
PopupMenu* menu = new PopupMenu(ui->pushButton, this); 
... 
ui->pushButton->setMenu(menu); 

Wygląda to tak:

enter image description here

+0

Dzięki, pracuję nad tym! Czy mogę zapytać, dlaczego istnieje 'QPushButton * b' w klasie' PopupMenu'? I czy funkcja 'showEvent' będzie wywoływana za każdym razem, gdy kliknę przycisk Push dla PopupMenu? – Ryan

+0

Ponadto natknąłem się na te błędy: '' popupmenu.obj: błąd LNK2001: nierozwiązany symbol zewnętrzny "public: virtual struct QMetaObject const * __cdecl PopupMenu :: metaObject (void) const" 'popupmenu.obj: błąd LNK2001: nierozwiązany symbol zewnętrzny" public: virtual void * __cdecl PopupMenu :: qt_metacast (const char *)”' '' popupmenu.obj: error LNK2001: nierozwiązanych zewnętrznych symbolu "public: virtual int __cdecl PopupMenu :: qt_metacall (enum QMetaObject :: Zaproszenie, int, void *)" ' I natknąłem się na te błędy, ale nie wiem też, dlaczego ma to związek z QMetaObject – Ryan

+0

@Ryan 'QPushButton * b' jest używane do informowania PopupMenu o tym, który przycisk powinien być ustawiony w tym samym kierunku. tak, 'showEvent' będzie wywoływane za każdym kliknięciem przycisku. o swoich błędach: spójrz na [to SO pytania i odpowiedzi] (http://stackoverflow.com/questions/14170770/unresolved-external-symbol-public-virtual-struct-qmetaobject-const-thiscal) –

1

Powinieneś zaimplementować eventFilter dla swojego QMenu. W metodzie eventFilter należy obliczyć pozycję, w której zostanie wyświetlone menu.

Tu masz przykład:

.pro

TEMPLATE = app 

QT  += widgets 
SOURCES += main.cpp \ 
      dialog.cpp 

HEADERS += dialog.h 

FORMS += dialog.ui 

main.cpp

#include <QtWidgets/QApplication> 

#include "dialog.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    Dialog dia; 
    return dia.exec(); 
} 

dialog.h

#ifndef DIALOG_H 
#define DIALOG_H 

#include <QtWidgets/QDialog> 
#include <QMenu> 
#include "ui_dialog.h" 

class Dialog : public QDialog 
{ 
    Q_OBJECT 
public: 
    Dialog(); 

protected: 
    bool eventFilter(QObject * obj, QEvent *event); 

private: 
    QMenu *menu; 
    Ui::Dialog m_ui; 
}; 

#endif 

dialog.cpp

#include "dialog.h" 

Dialog::Dialog() 
{ 
    m_ui.setupUi(this); 

    menu = new QMenu("menu", this); 
    menu->installEventFilter(this); 
    QAction *action = new QAction("action#1", this); 
    menu->addAction(action); 
    m_ui.pushButton->setMenu(menu); 
} 

bool Dialog::eventFilter(QObject * obj, QEvent *event) 
{ 
    if (event->type() == QEvent::Show && obj == m_ui.pushButton->menu()) 
    { 
     int menu_x_pos = m_ui.pushButton->menu()->pos().x(); 
     int menu_width = m_ui.pushButton->menu()->size().width(); 
     int button_width = m_ui.pushButton->size().width(); 

     QPoint pos = QPoint(menu_x_pos - menu_width + button_width, 
          m_ui.pushButton->menu()->pos().y()); 

     m_ui.pushButton->menu()->move(pos); 
     return true; 
    } 
    return false; 
} 
0

Innym (imho) prostszym rozwiązaniem byłoby:

void MainFrame::Slot_ShowMenu() 
{ 
    auto pMenu = new QMenu(this); 

    connect(pMenu, &QMenu::aboutToHide, pMenu, &QMenu::deleteLater); 

    ... 

    // Retrieve a valid width of the menu. (It's not the same as using "pMenu->width()"!) 
    int menuWidth = pMenu->sizeHint().width(); 

    int x = mUI.myQPushButton->width() - menuWidth; 
    int y = mUI.myQPushButton->height(); 

    QPoint pos(mUI.myQPushButton->mapToGlobal(QPoint(x, y))); 

    pMenu->popup(pos); 
}