由於我沒有找到答案,我必須自己實施這個控制。 這是一個彈出窗口小部件,使用QToolButton
作爲所有者。它可以根據項目的高度和所需的菜單高度將項目排列在網格中。
class myLabel:public QLabel
{
Q_OBJECT
// QObject interface
public:
myLabel(QWidget* parent=0):QLabel(parent){}
bool event(QEvent *e)
{
if(e->type()==QEvent::MouseButtonPress)
emit clicked();
return QLabel::event(e);
}
void setAction(QAction *a)
{
setText(a->text());
_action=a;
}
QAction* action()
{
return _action;
}
signals:
void clicked();
private:
QAction* _action;
};
class myMenu: public QWidget
{
Q_OBJECT
public:
myMenu(QWidget* owner,QWidget* parent=0):QWidget(parent){
this->setWindowFlags(Qt::Popup);
l = new QGridLayout(this);
l->setContentsMargins(QMargins(3,3,3,3));
_owner=owner;
QString style="QLabel:hover{background-color: white;} ";
setStyleSheet(style);
}
void addAction(QAction*a){_actions.append(a);}
QVector<QAction*> actions(){return _actions;}
void setItemHeight(int val){_itemHeight=val;}
void setHeight(int val){_height=val;}
private:
QVector<QAction*> _actions;
QGridLayout *l ;
QWidget*_owner;
int _itemHeight=30;
int _height=200;
private slots:
void popup()
{
clear();
//move popup under toolbutton
QPoint p = _owner->geometry().bottomLeft();
p.setY(p.y()+1);
this->move(_owner->parentWidget()->mapToGlobal(p));
//calculate rows count
int rows = _height/_itemHeight;
//calculate cols count
int cols = _actions.size()/rows;
int d = _actions.size()%rows;
if(d>0)
cols++;
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
{
int index = i+j*rows;
if(index<_actions.size())
{
myLabel *lb = new myLabel(this);
connect(lb,SIGNAL(clicked()),this,SLOT(onClick()));
lb->setFixedHeight(_itemHeight);
lb->setAction(_actions[index]);
l->addWidget(lb,i,j);
}
}
this->repaint();
this->show();
}
void clear()
{
while(l->itemAt(0)!=NULL)
{
QLayoutItem* i = l->takeAt(0);
if(i->widget())
delete i->widget();
if(i->layout())
delete i->layout();
delete i;
}
}
void onClick()
{
myLabel *g = qobject_cast<myLabel*>(sender());
g->action()->trigger();
close();
}
// QWidget interface
protected:
void closeEvent(QCloseEvent *)
{
qobject_cast<QToolButton*>(_owner)->setDown(false);
}
signals:
void closed();
};
還有一個示例顯示如何創建並填寫myMenu
以及如何接收選定的操作。
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//set-up myMenu, btMyMenu is a QToolButton
myMenu *mMenu = new myMenu(ui->btMyMenu,this);
connect(ui->btMyMenu,SIGNAL(pressed()),mMenu,SLOT(popup()));
for(int i=0;i<20;i++)
{
QAction *a = new QAction("Action "+QString::number(i),this);
connect(a,SIGNAL(triggered(bool)),this,SLOT(onActSelected()));
mMenu->addAction(a);
}
//mMenu can be customized
mMenu->setHeight(100);
mMenu->setItemHeight(50);
}
void MainWindow::onActSelected()
{
QAction *a = qobject_cast<QAction*>(sender());
ui->btMyMenu->setText(a->text());
}
有關如何改進此解決方案的任何意見,我們將不勝感激!
是否有原因不從QMenu派生並專門化? – Hayt
@Hayt Um ..好吧,我不知道子類QMenu如何幫助我...你有什麼想法嗎? – lena
不是真的,我只是會以爲你使用QMenu已有的功能,而不是自己重新實現它。 QMenu中保護的列數或大小提示的功能可以被覆蓋。我只是認爲你已經嘗試過並決定反對它。不知道你甚至沒有想過。 – Hayt