Проблема с кнопкой расширения панели инструментов Qt
Я должен добавить панель инструментов в 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 ответа
К сожалению, панели инструментов функционируют корректно только тогда, когда они встроены в QMainWindow. Хорошей новостью является то, что вы можете использовать QMainWindow, как если бы это был виджет. Вы можете привязать его к другому виджету, и тогда это не будет автономным окном. Я сделал это, и это работает хорошо. Я создавал объекты с использованием Qt Designer, и мне пришлось удалить строку меню QMainWindow, потому что Designer создает это автоматически.
Это не интуитивно понятная вещь, но она работает просто отлично, и это довольно легко изменить. Хорошо написанный комментарий, объясняющий, почему вы сделали это, вероятно, будет приветствоваться любым другим, читающим код в будущем...
Спасибо за ваш ответ, я пытался протестировать с помощью 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);
}
Итак, вот что я получаю, когда уменьшаю ширину окна:
Таким образом, результат правильный (и элементы управления работают, я их проверял), но теперь я хотел бы знать, возможно ли отображать список расширений по горизонтали, а не по вертикали? (Я имею в виду "прошедшее" действие справа от "открытого" действия, "сохранить" действие справа от прошлого действия и т. Д.) Спасибо за вашу помощь.