Qtoolbar toggle show hide on Qmenu - c++

How to add slot to toggle show and hide the toolbar in qmenu? This my code:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setMinimumSize(800, 600);
CreateAct();
CreateMenus();
createToolBars();
}
void MainWindow::CreateAct()
{
undoAct = new QAction(QIcon::fromTheme("edit-undo", QIcon(":/images/undo.png")), tr("&Undo"), this);
redoAct = new QAction(QIcon::fromTheme("edit-redo", QIcon(":/images/redo.png")), tr("&Redo"), this);
cutAct = new QAction(QIcon::fromTheme("edit-cut", QIcon(":/images/cut.png")), tr("Cu&t"), this);
copyAct = new QAction(QIcon::fromTheme("edit-copy", QIcon(":/images/copy.png")), tr("&Copy"), this);
pasteAct = new QAction(QIcon::fromTheme("edit-paste", QIcon(":/images/paste.png")), tr("&Paste"), this);
editToolBarAct = new QAction(tr("Show edit toolbar"), this);
editToolBarAct->setCheckable(true);
editToolBarAct->setChecked(true);
// connect(editToolBarAct, SIGNAL(toggled(bool)), editToolBar, SLOT());
fileToolBarAct = new QAction(tr("Show file toolbar"), this);
fileToolBarAct->setCheckable(true);
fileToolBarAct->setChecked(true);
// connect(fileToolBarAct, SIGNAL(toggled(bool)), fileToolBar, SLOT());
}
void MainWindow::CreateMenus()
{
windowMenu = menuBar()->addMenu(tr("&Window"));
windowMenu->addAction(fileToolBarAct);
windowMenu->addAction(editToolBarAct);
}
void MainWindow::createToolBars()
{
fileToolBar = addToolBar("file");
fileToolBar->addAction(undoAct);
fileToolBar->addAction(redoAct);
fileToolBar->toggleViewAction();
fileToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::LeftToolBarArea);
editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
editToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::LeftToolBarArea);
}
MainWindow::~MainWindow() {}
I am know using toggleViewAction, but how to use that code (I am really new in qt programming), can you give me sample code? I've tried googling, but did not find examples of its use.

The following small example demonstrates how to use the QToolBar::toggleViewAction():
class MainWindow : public QMainWindow
{
public:
MainWindow()
{
// Create a tool bar
QToolBar *tb = addToolBar("My Tool Bar");
[..]
// Create a menu and add toggle action for the tool bar.
QAction *tba = tb->toggleViewAction();
QMenu *m = menuBar()->addMenu("&Window");
m->addAction(tba);
}
};

Related

Creating sequenced tabs in Qt

A program has the main window, the menu bar, the menu item (QAction in Qt), the tab widget, the text edit. I try to receive the sequenced numeration in the tabs when I press on the menu item (New Tab).
When I press on the New Tab then tab 1, tab 2, tab 3, tab 4 and so on must appear.
The suggested approximate code is here:
MainWindow::MainWindow(QWidget* parent):QMainWindow(parent)
{
QMenuBar* menuBar = new QMenuBar(this);
setMenuBar(menuBar);
QMenu* fileMenu = new QMenu("&File", this);
menuBar->addMenu(fileMenu);
QAction* newTabAction = new QAction("&New Tab", this);
fileMenu->addAction(newTabAction);
connect(newTabAction, SIGNAL(triggered()), this, SLOT(newTabActionHandler()));
QTabWidget* tabWidget = new QTabWidget(this);
QList<QWidget*> widgetList;
widgetList.append(new QWidget(this));
tabWidget->addTab(widgetList[0], "Tab 0");
tabWidget->setMovable(true);
tabWidget->setTabsClosable(true);
QList<QTextEdit*> textEditList;
textEditList.append(new QTextEdit(this));
QVBoxLayout* vBoxLayout = new QVBoxLayout();
widgetList[0]->setLayout(vBoxLayout);
vBoxLayout->addWidget(textEditList[0]);
setCentralWidget(tabWidget);
}
void MainWindow::newTabActionHandler()
{
widgetList.append(new QWidget(this));
tabWidget->addTab(widgetList[widgetList.size()-1], ????);
textEditList.append(new QTextEdit(this));
QVBoxLayout* vBoxLayout = new QVBoxLayout();
widgetList[widgetList.size()-1]->setLayout(vBoxLayout);
vBoxLayout->addWidget(textEditList[textEditList.size()-1]);
}
Please, put the correct code into the line where question signs take place to be (in the newTabActionHandler() method body).
tabWidget->addTab(widgetList[widgetList.size()-1], ????);
Thank You!
You have to order your code, in this case you only need to use the size of the list. but I have given the freedom to correct your code, for example widgetList and textEditList are local variables so you can not access from the slot so it is appropriate that they are members of the class.
Another recommendation is to order your code, the more readable your code is, so you can create widget and textedit and make your links without using your containers.
mainwindow.cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void newTabActionHandler();
private:
QList<QWidget*> widgetList;
QList<QTextEdit*> textEditList;
QTabWidget* tabWidget;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QMenu>
#include <QMenuBar>
#include <QTextEdit>
#include <QVBoxLayout>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QMenuBar *menuBar = new QMenuBar(this);
setMenuBar(menuBar);
QMenu* fileMenu = new QMenu("&File", this);
menuBar->addMenu(fileMenu);
QAction *newTabAction = new QAction("&New Tab", this);
fileMenu->addAction(newTabAction);
connect(newTabAction, &QAction::triggered, this, &MainWindow::newTabActionHandler);
tabWidget = new QTabWidget(this);
tabWidget->setMovable(true);
tabWidget->setTabsClosable(true);
newTabActionHandler();
setCentralWidget(tabWidget);
}
void MainWindow::newTabActionHandler()
{
QWidget *widget = new QWidget;
widgetList << widget;
tabWidget->addTab(widget, QString("Tab %1").arg(widgetList.size()-1));
QTextEdit *textEdit = new QTextEdit;
textEditList << textEdit;
QVBoxLayout* vBoxLayout = new QVBoxLayout(widget);
vBoxLayout->addWidget(textEdit);
}
MainWindow::~MainWindow()
{
}
You can find the complete example in the following link
Replace ???? by QString("Tab %1").arg(widgetList.size()-1)

QMainWindow does not show Qwidgets background

I have a problem regarding a QWidget (custom made) inside a QMainWindow (custom made). My problem is that when I add my widget to my window as its central widget using setCentralWidget() method, it won't show the widgets background. It's important to show the background correctly.
Here is my MyWindow.cpp code:
#include "MyMainWindow.h"
MyMainWindow::MyMainWindow(QWidget * parent, Qt::WindowFlags flag) :
QMainWindow(parent, flag)
{
this->setFixedSize(1120, 630);
menu = new MyMenu(this);
// setting = new MySetting();
// tutorial = new MyTutorial();
// game = new MyGame();
this->setCentralWidget(menu);
this->show();
}
MyMainWindow::~MyMainWindow()
{
}
My MyMenu.cpp code:
#include "MyMenu.h"
MyMenu::MyMenu(QWidget *parent, Qt::WindowFlags f) :
QWidget(parent, f)
{
this->resize(1120, 630);
this->set_background();
this->construct_buttons();
this->construct_menu();
}
MyMenu::~MyMenu()
{
delete start;
delete setting;
delete tutorial;
delete exit;
delete buttons;
delete logo;
delete menu;
}
void MyMenu::construct_menu()
{
menu = new QVBoxLayout(this);
logo = new QLabel(this);
QPixmap *pixmap = new QPixmap("/home/kahrabian/ClionProjects/Shooter-AP93UT/Contents/logo.png");
logo->setPixmap(*pixmap);
logo->setAlignment(Qt::AlignHCenter);
menu->addWidget(logo);
menu->addLayout(buttons);
delete pixmap;
}
void MyMenu::construct_buttons()
{
buttons = new QHBoxLayout();
start = new QPushButton("Start", this);
buttons->addWidget(start);
setting = new QPushButton("Setting", this);
buttons->addWidget(setting);
tutorial = new QPushButton("Tutorial", this);
buttons->addWidget(tutorial);
exit = new QPushButton("Exit", this);
buttons->addWidget(exit);
}
void MyMenu::set_background()
{
QPalette *palette = new QPalette();
palette->setBrush(this->backgroundRole(),QBrush(QImage("/home/kahrabian/ClionProjects/Shooter-AP93UT/Contents/background_menu.jpg")));
this->setPalette(*palette);
delete palette;
}
My main.cpp code:
#include <QApplication>
#include "MyMenu.h"
#include "MyMainWindow.h"
int main(int argc, char **argv)
{
QApplication app (argc, argv);
MyMainWindow *mainwin = new MyMainWindow();
// MyMenu *MyMenu = new MyMenu();
// MyMenu->show();
return app.exec();
}
Can anyone help me with this problem??
Check this answer.
I would recommend you to use Qt style sheets.
You would need to call something like this:
setStyleSheet("image: url(path/to/background/image.png);");
on your widget.
Also, you might need to implement paintEvent() for widget to accept style sheets.
I'm usually doing it like this:
void MyWidget::paintEvent(QPaintEvent *pe)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
QWidget::paintEvent(pe);
}

Getting multiple inputs from QInputDialog in Qt

I would like to get a set of four values from four input labels in Qt. I would like to use QInputDialog but it contains only one inputbox as a default one. So, how can I add four labels and four line-edits and get the value from it?
You don't. The documentation is pretty clear:
The QInputDialog class provides a simple convenience dialog to get a
single value from the user.
If you want multiple values, create a QDialog derived class from scratch with 4 input fields.
For example:
QDialog dialog(this);
// Use a layout allowing to have a label next to each field
QFormLayout form(&dialog);
// Add some text above the fields
form.addRow(new QLabel("The question ?"));
// Add the lineEdits with their respective labels
QList<QLineEdit *> fields;
for(int i = 0; i < 4; ++i) {
QLineEdit *lineEdit = new QLineEdit(&dialog);
QString label = QString("Value %1").arg(i + 1);
form.addRow(label, lineEdit);
fields << lineEdit;
}
// Add some standard buttons (Cancel/Ok) at the bottom of the dialog
QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, &dialog);
form.addRow(&buttonBox);
QObject::connect(&buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
QObject::connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
// Show the dialog as modal
if (dialog.exec() == QDialog::Accepted) {
// If the user didn't dismiss the dialog, do something with the fields
foreach(QLineEdit * lineEdit, fields) {
qDebug() << lineEdit->text();
}
}
Following alexisdm's answer, here is one way to implement custom QInputDialog.
"inputdialog.h":
#ifndef INPUTDIALOG_H
#define INPUTDIALOG_H
#include <QDialog>
class QLineEdit;
class QLabel;
class InputDialog : public QDialog
{
Q_OBJECT
public:
explicit InputDialog(QWidget *parent = nullptr);
static QStringList getStrings(QWidget *parent, bool *ok = nullptr);
private:
QList<QLineEdit*> fields;
};
#endif // INPUTDIALOG_H
"inputdialog.cpp":
#include "inputdialog.h"
#include <QLabel>
#include <QLineEdit>
#include <QDialogButtonBox>
#include <QFormLayout>
InputDialog::InputDialog(QWidget *parent) : QDialog(parent)
{
QFormLayout *lytMain = new QFormLayout(this);
for (int i = 0; i < 4; ++i)
{
QLabel *tLabel = new QLabel(QString("Text_%1:").arg(i), this);
QLineEdit *tLine = new QLineEdit(this);
lytMain->addRow(tLabel, tLine);
fields << tLine;
}
QDialogButtonBox *buttonBox = new QDialogButtonBox
( QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, this );
lytMain->addWidget(buttonBox);
bool conn = connect(buttonBox, &QDialogButtonBox::accepted,
this, &InputDialog::accept);
Q_ASSERT(conn);
conn = connect(buttonBox, &QDialogButtonBox::rejected,
this, &InputDialog::reject);
Q_ASSERT(conn);
setLayout(lytMain);
}
QStringList InputDialog::getStrings(QWidget *parent, bool *ok)
{
InputDialog *dialog = new InputDialog(parent);
QStringList list;
const int ret = dialog->exec();
if (ok)
*ok = !!ret;
if (ret) {
foreach (auto field, dialog->fields) {
list << field->text();
}
}
dialog->deleteLater();
return list;
}
Now you can use getStrings() method similar to QInputDialog::getText():
QStringList list = InputDialog::getStrings(this);
if (!list.isEmpty()) {
// use list
}
Or
bool ok;
QStringList list = InputDialog::getStrings(this, &ok);
if (ok) {
// use list
}

Transitioning between menu screens with QStateMachine

I am considering transitioning between menu screens in a game by using QStateMachine. However, I'm unsure how to kick off some code (e.g. show() a QWidget) upon a transition between states occurring. I can do it quite easily with plain old signals (see commented out code), but I figure that I could probably do some fancy animation upon switching screens using transitions.
Here's my code:
Edit: updated as per Koying's suggestion.
ApplicationWindow.h:
#include <QtGui>
#include <QStateMachine>
#include "MainMenu.h"
#include "LoadGameMenu.h"
class ApplicationWindow : public QMainWindow
{
Q_OBJECT
public:
ApplicationWindow();
private slots:
void mainMenuButtonClicked();
void loadGameMenuButtonClicked();
private:
MainMenu* mainMenu;
LoadGameMenu* loadGameMenu;
QStateMachine stateMachine;
QStackedWidget* stack;
};
ApplicationWindow.cpp:
ApplicationWindow::ApplicationWindow()
{
resize(800, 600);
stack = new QStackedWidget(this);
mainMenu = new MainMenu();
setCentralWidget(mainMenu);
loadGameMenu = new LoadGameMenu();
QState* mainMenuState = new QState();
QState* loadGameMenuState = new QState();
QAbstractTransition* loadTransition = mainMenuState->addTransition(
mainMenu, SIGNAL(loadGameClicked()), loadGameMenuState);
connect(loadTransition, SIGNAL(triggered()), this, SLOT(loadGameMenuButtonClicked()));
QAbstractTransition* mainMenuTransition = loadGameMenuState->addTransition(
loadGameMenu, SIGNAL(backToMainMenuClicked()), mainMenuState);
connect(mainMenuTransition, SIGNAL(triggered()), this, SLOT(mainMenuButtonClicked()));
stateMachine.addState(mainMenuState);
stateMachine.addState(loadGameMenuState);
stateMachine.setInitialState(mainMenuState);
stateMachine.start();
}
void ApplicationWindow::mainMenuButtonClicked()
{
setCentralWidget(mainMenu);
}
void ApplicationWindow::loadGameMenuButtonClicked()
{
setCentralWidget(loadGameMenu);
}
LoadGameMenu.h:
#include <QtGui>
class LoadGameMenu : public QWidget
{
Q_OBJECT
public:
LoadGameMenu();
signals:
void backToMainMenuClicked();
private:
QPushButton* loadGameButton;
QPushButton* backToMainMenuButton;
};
LoadGameMenu.cpp:
#include "LoadGameMenu.h"
LoadGameMenu::LoadGameMenu()
{
loadGameButton = new QPushButton(tr("Load"));
backToMainMenuButton = new QPushButton(tr("Main Menu"));
QObject::connect(backToMainMenuButton, SIGNAL(clicked()),
this, SIGNAL(backToMainMenuClicked()));
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(loadGameButton);
layout->addWidget(backToMainMenuButton);
layout->setContentsMargins(300, 400, 300, 200);
setLayout(layout);
}
MainMenu.h:
#include <QtGui>
class MainMenu : public QWidget
{
Q_OBJECT
public:
MainMenu();
signals:
void newGameClicked();
void loadGameClicked();
private slots:
void exit();
private:
QPushButton* newGameButton;
QPushButton* loadGameButton;
QPushButton* exitGameButton;
QMenu* fileMenu;
};
MainMenu.cpp:
#include "MainMenu.h"
MainMenu::MainMenu()
{
newGameButton = new QPushButton(tr("New Game"), this);
loadGameButton = new QPushButton(tr("Load Game"));
exitGameButton = new QPushButton(tr("Exit"));
QObject::connect(newGameButton, SIGNAL(clicked()), this, SIGNAL(newGameClicked()));
QObject::connect(loadGameButton, SIGNAL(clicked()), this, SIGNAL(loadGameClicked()));
QObject::connect(exitGameButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(newGameButton);
layout->addWidget(loadGameButton);
layout->addWidget(exitGameButton);
layout->setContentsMargins(300, 200, 300, 200);
setLayout(layout);
}
void MainMenu::exit()
{
if( QMessageBox::question(
this,
tr("Exit?"),
tr("Do you really want to exit the game?"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No
) == QMessageBox::Yes
)
{
qApp->quit();
}
}
main.cpp:
#include <QtGui>
#include "ApplicationWindow.h"
int main(int argv, char **args)
{
QApplication app(argv, args);
ApplicationWindow window;
window.show();
return app.exec();
}
So, how do I trigger some behaviour or action when a transition occurs?
Cheers.
To actually do something on a state transition, you have to connect to the triggered() signal of the transition, e.g.
QAbstractTransition* trMainLoad = mainMenuState->addTransition(mainMenu, SIGNAL(loadGameClicked()), loadGameMenuState);
connect(trMainLoad , SIGNAL(triggered()), SLOT(...));

QT separator widget?

Greetings all,
Is there any widget to separate two QWidgets and also give full focus to a one widget.
As shown in following figure ?
Thanks in advance,
umanga
How about QSplitter?
QWidget 1, for exmaple, QListView. QWidget 2 is a combination of QWidgets (the left part is simple QPushButton with show/hide caption, and the right part another widget)... All you have to do, is to hide your QWidget2 when user clicked on QPushButton...
If you need an example, I may post it.
Updated
main.cpp
#include "splitter.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
splitter w;
w.show();
return a.exec();
}
splitter.h
#ifndef SPLITTER_H
#define SPLITTER_H
#include <QtGui/QDialog>
class splitter : public QDialog
{
Q_OBJECT;
QWidget* widget1;
QWidget* widget2;
QPushButton* button;
public:
splitter(QWidget *parent = 0, Qt::WFlags flags = 0);
~splitter();
private slots:
void showHide(void);
};
#endif // SPLITTER_H
splitter.cpp
#include <QtGui>
#include "splitter.h"
splitter::splitter(QWidget *parent, Qt::WFlags flags)
: QDialog(parent, flags)
{
QApplication::setStyle("plastique");
QListView* listView = new QListView;
QTableView* tableView = new QTableView;
button = new QPushButton("Hide >");
widget1 = new QWidget;
QHBoxLayout* w1Layout = new QHBoxLayout;
w1Layout->addWidget(listView);
w1Layout->addWidget(button);
widget1->setLayout(w1Layout);
widget2 = new QWidget;
QHBoxLayout* w2Layout = new QHBoxLayout;
w2Layout->addWidget(tableView);
widget2->setLayout(w2Layout);
QSplitter *mainSplitter = new QSplitter(this);
mainSplitter->addWidget(widget1);
mainSplitter->addWidget(widget2);
connect(button, SIGNAL(clicked()), this, SLOT(showHide()));
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(mainSplitter);
setLayout(mainLayout);
}
splitter::~splitter()
{}
void splitter::showHide(void)
{
if (widget2->isVisible())
{ // hide
widget2->setVisible(false);
button->setText("< Show");
}
else
{ // show
widget2->setVisible(true);
button->setText("Hide >");
}
}