2015-07-28 3 views
5

Ich schreibe ein Popup-Menü für ein Qt-Drucktasten-Widget, sobald der Druckknopf angeklickt wird, erscheint ein Popup-Menü (unter dem Druckknopf).Position (nach rechts) von Qt PushButton Popup-Menü setzen

Das Popup-Menü ist standardmäßig links unten. Gibt es irgendwelche Möglichkeiten, das Popup-Menü auf der rechten Seite unterhalb der Drucktaste zu öffnen?

Es gibt keine Funktion zum Einstellen der Position ... also frage ich mich, ob es eine ausgeklügelte Art und Weise gibt, dies zu tun?

Hier sind einige Code (für Pop-up-Menü):

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 

Vielen Dank für jede Orientierung und Beratung.

Antwort

5

Dies kann durch Subklassen QMenu und Bewegen des Popup-Menü durchgeführt werden, wo Sie es in showEvent haben wollen:

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

Es sieht wie folgt aus:

enter image description here

+0

Danke, ich arbeite daran! Darf ich fragen, warum es 'QPushButton * b 'in der Klasse' PopupMenu' gibt? Und wird die 'showEvent' Funktion jedes Mal aufgerufen, wenn ich auf den Push Button für das PopupMenu klicke? – Ryan

+0

Außerdem bin ich auf diese Fehler gestoßen:'' popupmenu.obj: Fehler LNK2001: nicht aufgelöstes externes Symbol "public: virtuelle Struktur QMetaObject const * __cdecl PopUpMenu :: metaObject (void) const" 'popupmenu.obj: Fehler LNK2001: nicht aufgelöstes externes Symbol" public: virtual void * __cdecl PopupMenu :: qt_metacast (char const *)“' ' ' popupmenu.obj: Fehler LNK2001: extern Symbol "public: virtual int __cdecl PopupMenu :: qt_metacall (enum QMetaObject :: Anruf, int, void * *)" ' I stieß auf diese Art Fehler zuvor, aber ich weiß auch nicht, warum es mit QMetaObject in Verbindung steht – Ryan

+0

@Ryan 'QPushButton * b' wird verwendet, um dem PopupMenu zu sagen, an welcher Button-Instanz es ausgerichtet werden sollte. Ja, 'showEvent' wird jedes Mal aufgerufen, wenn auf die Schaltfläche geklickt wird. über Ihre Fehler: werfen Sie einen Blick auf [diese SO Frage und Antworten] (http://stackoverflow.com/questions/14170770/unresolved-external-symbol-public-virtual-struct-qmetaobject-const-thiscal) –

1

Sie sollten eine eventFilter für Ihre QMenu implementieren. In der eventFilter Methode müssen Sie die Position berechnen, wo Ihr Menü angezeigt wird.

Hier haben Sie ein Beispiel:

.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

Weitere (imho) einfacher Ansatz wäre:

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); 
} 
Verwandte Themen