Qt工具栏扩展按钮问题

时间:2016-11-14 20:25:45

标签: qt qtoolbar

我必须在Qt中添加一个工具栏,就像菜单栏下的Windows文件系统资源管理器一样(我在Windows 7下),这意味着当窗口宽度减小时,图标不够用要显示的位置会自动隐藏并放入下拉列表(单击工具栏右侧显示的箭头时会显示该列表)。我首先将我找到的代码粘贴到网上:

#include <QApplication>
#include <QAction>
#include <QMainWindow>
#include <QLineEdit>
#include <QToolBar>
#include <QHBoxLayout>



void initWindow(QMainWindow* w);


int main(int argc, char *argv[])
{
    Q_INIT_RESOURCE(application);

    QApplication app(argc, argv);

    QMainWindow mainWin;
    initWindow(&mainWin);
    mainWin.show();


    return app.exec();
}




void initWindow(QMainWindow* w)
{
    QLineEdit* searchBar = new QLineEdit;

    QAction* newAct = new QAction(QIcon(":/images/new.png"), "&New", w);
    newAct->setShortcuts(QKeySequence::New);

    QAction* openAct = new QAction(QIcon(":/images/open.png"), "&Open...", w);
    openAct->setShortcuts(QKeySequence::Open);

    QAction* saveAct = new QAction(QIcon(":/images/save.png"), "&Save", w);
    saveAct->setShortcuts(QKeySequence::Save);

    QAction* cutAct = new QAction(QIcon(":/images/cut.png"), "Cu&t", w);
    cutAct->setShortcuts(QKeySequence::Cut);

    QAction* copyAct = new QAction(QIcon(":/images/copy.png"), "&Copy", w);
    copyAct->setShortcuts(QKeySequence::Copy);

    QAction* pasteAct = new QAction(QIcon(":/images/paste.png"), "&Paste", w);
    pasteAct->setShortcuts(QKeySequence::Paste);


    QToolBar* fileToolBar = w->addToolBar("File");
    fileToolBar->addAction(newAct);
    fileToolBar->addAction(openAct);
    fileToolBar->addAction(saveAct);

    QToolBar* editToolBar = w->addToolBar("Edit");
    editToolBar->addAction(cutAct);
    editToolBar->addAction(copyAct);
    editToolBar->addAction(pasteAct);
    editToolBar->addWidget(searchBar);

}

...但问题是代码只适用于工具栏到QMainWindow(并使用QMainWindow :: addToolbar()方法添加)。但是在我工作的代码中,我必须将其转换为QWidget,而不是QWindow。所以我创建了一个水平布局,我添加了几个小部件(一个QLineEdit和几个QAction),它适用于QAction而不适用于QLineEdit:当我点击箭头时,所有隐藏的QAction都是可见的,但不是QLineEdit。这是我的代码:

#include <QApplication>
#include <QtGui/QWindow>
#include <QToolbar>
#include <QVBoxLayout>
#include <QMainWindow>
#include <QPushButton>
#include <QAction>
#include <QIcon>
#include <QLineEdit>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget* w = new QWidget;


    QHBoxLayout* tb1 = new QHBoxLayout;
    tb1->addWidget(new QPushButton("item11"));
    tb1->addWidget(new QPushButton("item12"));
    tb1->addWidget(new QPushButton("item13"));
    tb1->addWidget(new QPushButton("item14"));

    QHBoxLayout* spacerLayout = new QHBoxLayout;
    spacerLayout->addSpacerItem(new QSpacerItem(50, 20, QSizePolicy::MinimumExpanding,QSizePolicy::Fixed) );
    spacerLayout->setAlignment(Qt::AlignJustify);

    QWidget* sep = new QWidget;
    QRect rect = sep->geometry();
    rect.setWidth(0);
    sep->setGeometry(rect);
    QToolBar* tb3 = new QToolBar;
    QLineEdit* searchBar = new QLineEdit;
    QAction* item31 = new QAction(QIcon(":/images/cut.png"), "cut");
    QAction* item32 = new QAction(QIcon(":/images/copy.png"), "copy");
    QAction* item33 = new QAction(QIcon(":/images/open.png"), "open");
    QAction* item34 = new QAction(QIcon(":/images/paste.png"), "past");
    QAction* item35 = new QAction(QIcon(":/images/save.png"), "save");
    tb3->addWidget(sep);
    tb3->addWidget(searchBar);
    tb3->addAction(item31);
    tb3->addAction(item32);
    tb3->addAction(item33);
    tb3->addAction(item34);
    tb3->addAction(item35);

    QVBoxLayout* mainLayout = new QVBoxLayout;
    QHBoxLayout* topLayout = new QHBoxLayout;

    topLayout->addLayout(tb1);
    topLayout->addLayout(spacerLayout);
    topLayout->addWidget(tb3);


    QHBoxLayout* bottomLayout = new QHBoxLayout;
    bottomLayout->addWidget(new QPushButton);

    mainLayout->addLayout(topLayout);
    mainLayout->addLayout(bottomLayout);

    w->setLayout(mainLayout);
    w->show();

    return app.exec();
}

这些是第二个解决方案的结果截图:我首先启动应用程序:

http://img4.hostingpics.net/pics/224120tb1.jpg

当我减小它的宽度时,右侧的小部件消失了。然后我点击箭头将它们显示在下拉列表中,除QLineEdit外都显示它们:

http://img4.hostingpics.net/pics/903380tb2.jpg

这里有人知道问题是什么吗?感谢。

2 个答案:

答案 0 :(得分:2)

令人遗憾的是,工具栏只有在嵌入QMainWindow时才能正常工作。好消息是你可以使用QMainWindow,就像它是一个小部件一样。您可以将其父级添加到另一个小部件,然后它不会成为独立窗口。我做到了这一点,效果很好。我正在使用Qt Designer创建对象,我不得不删除QMainWindow菜单栏,因为Designer会自动创建它。

这不是一个直观的事情,但它运作得很好,而且这是一个相当容易的改变。一份写得很好的评论解释了为什么你这样做可能会受到其他人在将来阅读代码的欢迎......

答案 1 :(得分:0)

感谢您的回答,我尝试使用QMainWindow进行测试,但它完全搞砸了我工作的布局,因为它是一个复杂的窗口(过去很多人都在研究它)而我必须尽快完成我的工作我更喜欢尝试新的方法。因此,经过对网络的一些研究后,我发现即使工具栏没有进入QMainWindow也可以这样做,但我必须将我想要的所有QWidget替换为QToolBar一个派生QWidgetAction的类,并将它们实例化为QWidgetAction :: createWidget()方法。所以我做了这个正常工作的代码:

main.cpp:

#include <QApplication>
#include <QtGui/QWindow>
#include <QToolbar>
#include <QVBoxLayout>
#include <QMainWindow>
#include <QPushButton>
#include <QAction>
#include <QIcon>
#include <QLineEdit>
#include <QSlider>
#include <QVariant>
#include <QCheckBox>
#include <QWidgetAction>

#include "QMyWidgetAction.h"


void test2(QApplication& app);




int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    test2(app);
    return app.exec();
}

void test2(QApplication& app)
{

    QWidget* w = new QWidget;

    QHBoxLayout* l1 = new QHBoxLayout;
    l1->addWidget(new QPushButton("item11"));
    l1->addWidget(new QPushButton("item12"));
    l1->addWidget(new QPushButton("item13"));
    l1->addWidget(new QPushButton("item14"));

    QHBoxLayout* l2 = new QHBoxLayout;
    l2->addSpacerItem(new QSpacerItem(50, 20, QSizePolicy::MinimumExpanding,QSizePolicy::Fixed) );
    l2->setAlignment(Qt::AlignJustify);

    QHBoxLayout* l3 = new QHBoxLayout;
    QToolBar* tb = new QToolBar;
    l3->addWidget(tb);


    QAction* item31 = new QAction(QIcon(":/images/cut.png"), "cut");
    QAction* item32 = new QAction(QIcon(":/images/copy.png"), "copy");
    QAction* item33 = new QAction(QIcon(":/images/open.png"), "open");
    QAction* item34 = new QAction(QIcon(":/images/paste.png"), "past");
    QAction* item35 = new QAction(QIcon(":/images/save.png"), "save");
    QLineEdit* searchBar = new QLineEdit;
    QMyWidgetAction* widgetAction = new QMyWidgetAction(tb);
    QLineEditAction* lineEditAction = new QLineEditAction(tb);

    tb->addSeparator();
    tb->addWidget(searchBar);
    tb->addAction(item31);
    tb->addAction(item32);
    tb->addAction(item33);
    tb->addAction(item34);
    tb->addAction(item35);
    tb->addAction(widgetAction);
    tb->addAction(lineEditAction);

    QVBoxLayout* mainLayout = new QVBoxLayout;
    QHBoxLayout* topLayout = new QHBoxLayout;


    topLayout->addLayout(l1);
    topLayout->addLayout(l2);
    topLayout->addLayout(l3);


    QHBoxLayout* bottomLayout = new QHBoxLayout;
    bottomLayout->addWidget(new QPushButton);

    mainLayout->addLayout(topLayout);
    mainLayout->addLayout(bottomLayout);

    w->setLayout(mainLayout);
    w->show();

}

QMyWidgetAction.h:

#ifndef QMAYAWIDGETACTION_H
#define QMAYAWIDGETACTION_H

#include <QObject>
#include <QWidget>

#include <QWidgetAction>

class QLineEdit;

class QMyWidgetAction : public QWidgetAction
{
    Q_OBJECT
public:
    QMyWidgetAction(QWidget* parent);
    QWidget* createWidget(QWidget* parent);

};


class QLineEditAction : public QWidgetAction
{
    Q_OBJECT
public:
    QLineEditAction(QWidget* parent);
    QWidget* createWidget(QWidget* parent);

protected slots:
    virtual void    searchTextChanged(const QString& text);

private:
     QLineEdit* fWidget;

};

#endif // QMAYAWIDGETACTION_H

QMyWidgetAction.cpp:

#include <QApplication>
#include <QtGui/QWindow>
#include <QToolbar>
#include <QVBoxLayout>
#include <QMainWindow>
#include <QPushButton>
#include <QAction>
#include <QIcon>
#include <QLineEdit>
#include <QSlider>
#include <QVariant>
#include <QCheckBox>
#include <QWidgetAction>

#include "QMyWidgetAction.h"


QMyWidgetAction::QMyWidgetAction(QWidget* parent)
    : QWidgetAction(parent)
{

}


QWidget* QMyWidgetAction::createWidget(QWidget* parent)
{
    QPushButton* widget = new QPushButton("bouton", parent);
    widget->setMinimumSize(100, 30);
    return widget;
}


QLineEditAction::QLineEditAction(QWidget* parent)
    : QWidgetAction(parent)
{

}


QWidget* QLineEditAction::createWidget(QWidget* parent)
{
    fWidget = new QLineEdit(parent);
    connect(fWidget, SIGNAL(textChanged(QString)), this, SLOT(searchTextChanged(QString)));
    fWidget->setMinimumSize(100, 30);
    return fWidget;
}


void QLineEditAction::searchTextChanged(const QString& text)
{
    fWidget->setMinimumWidth(fWidget->minimumWidth() + 10);
}

所以现在这是我缩小窗口宽度时得到的结果:

enter image description here

所以结果是正确的(控件工作,我测试了它们),但现在我想知道是否可以水平而不是垂直显示扩展名列表? (我的意思是&#34;过去&#34;行动在&#34;开放&#34;行动,&#34;保存&#34;行动在过去行动的权利等。)感谢您的帮助。< / p>