2015-07-28 17 views
5

Düğme tıklatıldığında, bir Qt basma düğmesi widget'ına yönelik bir açılır menü, bir menü açılır menüsü (basma düğmesinin altında) yazıyorum.Qt PushButton'un konumunu ayarlayın (sağa) Popup Menüsü

Açılır menü, varsayılan olarak aşağıda sol taraftadır. Açılır menünün, basma düğmesinin altında sağ tarafta açılmasını sağlayan herhangi bir yol var mı?

Ayarlanmış bir konum işlevi yok ... bu yüzden bunu yapmak için karmaşık bir yol olup olmadığını merak ediyorum?

İşte (açılır menü için) bazı kod şunlardır:

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 

herhangi rehberlik ve tavsiye için çok teşekkür ederiz.

cevap

5

sen showEvent içinde olmasını istediğiniz yerdir QMenu sınıflara ve açılır menüden hareket ettirerek yapılabilir:

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

Bu şuna benzer:

enter image description here

+0

Teşekkürler, bunun üzerinde çalışıyorum! PopupMenu sınıfında QPushButton * b'nin neden olduğunu sorabilir miyim? Ve PopupMenu için Basma Düğmesine her tıkladığımda 'showEvent' işlevi çağrılacak mı? – Ryan

+0

Ayrıca, bu hatalara rastladım: '' popupmenu.obj: error LNK2001: çözümlenmemiş harici sembol "public: sanal struct QMetaObject const * __cdecl PopupMenu :: metaObject (void) const" : popupmenu.obj: hata LNK2001: çözümlenmemiş harici sembol "public: sanal void * __cdecl PopupMenu :: qt_metacast (Char const *)"' ' ' popupmenu.obj: LNK2001 hatası: çözülmemiş dış simge "kamu: sanal int __Cdecl PopupMenu :: qt_metacall (enum QMetaObject :: Çağrı, int, geçersiz * *)" ' ben Daha önce bu tür hatalarla karşılaştım, ama aynı zamanda neden QMetaObject – Ryan

+0

@Ryan 'QPushButton * b' ile ilgili olduğunu da bilmiyorum. PopupMenu'ya hangi düğme örneğinin hizalanması gerektiğini anlatmak için kullanılır. evet, butona tıklandığında her defasında "showEvent" çağrılır. hatalarınız hakkında: [bu SO sorusuna ve cevaplarına bakınız] (http://stackoverflow.com/questions/14170770/unresolved-external-symbol-public-virtual-struct-qmetaobject-const-thiscal) –

1

QMenu için eventFilter uygulamalısınız. eventFilter yönteminde, menünüzün gösterileceği konumu hesaplamanız gerekir. İşte

Eğer bir örnek vardır:

.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

Başka (imho) daha basit bir yaklaşım olur:

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