So I have menu bar like this:
this->layout = new QGridLayout;
QMenuBar* menuBar = new QMenuBar();
QMenu *fileMenu = new QMenu("File");
menuBar->addMenu(fileMenu);
fileMenu->addAction("Exit");
this->layout->setMenuBar(menuBar);
And I am wonderig how to connect thie action "Exit" with some slot my QWidget, I tryed something like this:
connect(menuBar,SIGNAL(menuBar->actions),this,SLOT(exitGame()));
But it is not working, can you tell me what I am doing wrong? And yes I have read manual about QMenuBar bud there are no examples of connecting. I have read about some connecting in Qt Designer but I am not using it.
You need to connect the QAction pointer returned from QMenuBar::addAction to the slot...
auto *exit_action = fileMenu->addAction("Exit");
connect(exit_action, &QAction::triggered,
[this](bool checked)
{
exitGame();
});
Related
I want to show a tick item on selecting particular item from my QMenu.
Currently its showing the menus, but I need to keep a kick also so that next time user can know which is selected before.
QMenu *preferenceMenu = new QMenu();
preferenceMenu = editMenu->addMenu(tr("&Preferences"));
QMenu *Mode1 = new QMenu();
Mode1 = preferenceMenu->addMenu(tr("&Mode 1"));
Mode1->addAction(new QAction(tr("&Menu1"), this));
QMenu *Mode2 = new QMenu();
Mode2 = preferenceMenu->addMenu(tr("&Mode 2"));
Mode2->addAction(new QAction(tr("&Menu2"), this));
Mode2->addAction(new QAction(tr("&Menu3"), this));
On QAction I call slot slotActionTriggered(QAction* actionSelected).
void csTitleBar::slotActionTriggered(QAction* actionSelected)
{
actionSelected->setChecked(true);
}
Here if I select Menu3, a tick also should appear right side of Menu3 and later if I change to Menu2, tick should show on Menu2 and disappear from Menu3.
Please give some idea, whether Qt have some default method to do it or I need to keep widget or image.
You have to make actions checkable via QAction::setCheckable.
QMenu *Mode2 = new QMenu();
Mode2 = preferenceMenu->addMenu(tr("&Mode 2"));
Mode2->addAction(new QAction(tr("&Menu2"), this));
Mode2->actions().back()->setCheckable(true);
Mode2->addAction(new QAction(tr("&Menu3"), this));
Mode2->actions().back()->setCheckable(true);
Also, there is no need to check actions manually in your case, marking them as checkable already does the job.
As mentioned by #G.M., to make some of them mutually exclusive, you have to create a QActionGroup for each set (Menu2 and Menu3 in your case). Just set the action group as the parent of the action or call QActionGroup::addAction.
QMenu* Mode2 = new QMenu();
QActionGroup* Mode2ActionGroup = new QActionGroup(Mode2);
Mode2 = preferenceMenu->addMenu(tr("&Mode 2"));
Mode2->addAction(new QAction(tr("&Menu2"), Mode2ActionGroup));
Mode2->actions().back()->setCheckable(true);
Mode2->addAction(new QAction(tr("&Menu3"), Mode2ActionGroup));
Mode2->actions().back()->setCheckable(true);
PS: although links redirect to Qt 5.xx documentation, solution works in both Qt 4.8 and Qt 5.xx.
In a QWidget like QLabel, how can we set a "?" button, such that when clicked (or hovered) it should show some help text.
Also you can use QMenu instead of QPushButton + QLabel.
// Constructor
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotCustomMenu(QPoint)));
// slotCustomMenu(QPoint)
QMenu menu(this);
menu.addAction(this->toolTip());
menu.addAction(this->whatsThis());
menu.exec(QCursor::pos());
Easiest way to show help when hover QWidget: setToolTip(QString) and setToolTipDuration(int).
If you want a "?" button, just implement your own QWidget. Then via ui designer or directly in your code add QPushButton and QLabel on layout, and show your QLabel with help text in position of cursor when clicked(). Something like this:
{
// Constructor
...
m_mainLabel = new QLabel("Main text");
m_button = new QPushButton("?");
m_helpLabel = new QLabel("Help text");
connect(m_button, SIGNAL(clicked(bool)),
this, SLOT(slotShowOrHideHelpLabel(bool)));
QHBoxLayout *hBoxLayout = new QHBoxLayout;
hBoxLayout->addWidget(m_mainLabel);
hBoxLayout->addWidget(m_button);
setLayout(hBoxLayout);
}
void slotShowOrHideHelpLabel(bool showHelpLabel)
{
if (showHelpLabel)
{
m_helpLabel->show();
m_helpLabel->move(QCursor::pos());
}
else
{
m_helpLabel->hide();
}
}
I have a Qt Application which i want to show in the System Tray.
My desired behavior is that if the user clicks the close button of the Application than that application hides in the system tray but does not exit.
My code in main.cpp is :
if (QSystemTrayIcon::isSystemTrayAvailable())
{
QObject *root = engine.rootObjects().at(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(root);
QAction *showAction = new QAction(QObject::tr("Show"), window);
window->connect(showAction, SIGNAL(triggered()), window, SLOT(show()));
QAction *hideAction = new QAction(QObject::tr("Hide"), window);
window->connect(hideAction, SIGNAL(triggered()), window, SLOT(hide()));
QAction *quitAction = new QAction(QObject::tr("&Quit"), window);
window->connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
QObject::connect(qApp,SIGNAL(aboutToQuit()),window,SLOT(hide()));
QMenu *trayIconMenu = new QMenu();
trayIconMenu->addAction(showAction);
trayIconMenu->addAction(hideAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);
QSystemTrayIcon *trayIcon = new QSystemTrayIcon(window);
trayIcon->setContextMenu(trayIconMenu);
trayIcon->setToolTip("xxx");
trayIcon->setIcon(QIcon("xxx.png"));
trayIcon->show();
}
Now i am not able to connect the aboutToQuit signal and hide the application in the tray i.e
QObject::connect(qApp,SIGNAL(aboutToQuit()),window,SLOT(hide())); line is not correct but i am not getting any errors etc.
Apart from this everything is working correctly.Can someone please tell me what i am doing wrong and how can i achieve my desired behavior.
I would also like to know whether i have got the right signal to connect or whether i should try connecting to some other signal.
Thanks in advance.
You can use :
qApp()->setQuitOnLastWindowClosed(false);
quitOnLastWindowClosed property is true by default which causes your application to quit when the last window is closed. By setting it to false, your application does not terminate when you close the main window.
You can also reimplement closeEvent of your main widget, ignore the close event and just hide your window :
void MainWindow::closeEvent(QCloseEvent * e)
{
e->ignore();
this->hide();
}
I've made some QPushbuttons like QPushButton **btn and I want to know when the user clicks on one of them using QMouseEvent here is the code but this idea does not work at all any ideas??
void Game::mousePressEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::LeftButton)
{
btn[ev->x()][ev->y()].setStyleSheet("background-color : black;");
}
else
{
btn[ev->x()][ev->y()].setStyleSheet("background-color : red;");
}
that else part is for right click
and here is the code that generates the buttons
void Game::MakeButton()
{
btn = new ApButton*[column];
hrztl = new QHBoxLayout[column];
hrztl->setSpacing(0);
for(int i=0; i<column;i++)
{
btn[i] = new ApButton[row];
for(int j=0; j<row; j++)
{
btn[i][j].setRowCol(i,j);
btn[i][j].setFixedSize(50,50);
hrztl[i].addWidget(&btn[i][j]);
}
ui->MainLayout->addLayout(&hrztl[i]);
}
ui->MainLayout->setSpacing(0);
}
ApButton is a class that inherits QPushButton
This is a good example of use for a QSignalMapper, as seen there: http://qt-project.org/doc/qt-5.0/qtcore/qsignalmapper.html#details
ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);
QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}
connect(signalMapper, SIGNAL(mapped(QString)),
this, SIGNAL(clicked(QString)));
setLayout(gridLayout);
}
In that example, every button is identified by its title, as a QString. The mapper allows you to retrieve the corresponding button's title when one of them is clicked.
Switch your
Game::mousePressEvent(QMouseEvent *e)
to
ApButton::mousePressEvent(QMouseEvent *e)
since you are trying to implement the Press Event of the Button. If you only want to have the moment of the button being pressed and not changing Button behaviour with this, use a SIGNAL/SLOT connection instead of reimplementing the event (add to your creation):
connect(btn[i][j], SIGNAL(pressed()), this, SLOT(slotButtonPressed());
void Game::slotButtonPressed(){
//doSomething
}
use a QButtonGroup or the QSignalMapper if you need to identify more then one Button in a single method or use QObject::sender(), but this can be tricky sometimes.
I had a similar situations some times ago.. I had a QDialog and I had to dinamically add some QPushButton.. then I need to know on which button the user pressed.. so I needed something like:
connect( btn, SIGNAL( clicked(int) ),
this, SLOT( handle(int) ));
for instance a signal-slot connection with the id of the clicked button and a function for handle the click. The function is the same for each buttons and can handle the specific button because of the id..
Implementing this is quite simple subclassing QPushButton adding an id and a new signal..
Hope it's some help!
If Apbutton inherits QPushButton, why don't connect to clicked()?
then you can call QObject::sender()
On slot:
ApButton *but = dynamic_cast<ApButton*>QObject::sender()
if(but)
{
but->setStyleSheet("background-color : black;");
}
to get the clicked buttonbutton and set its stylesheet
I'm creating a text editor and I'd like to put the QComboBox in the QMenu. I didn't find any method inside the QMenu that handled such a thing. The closest is QMenu::addAction(). I was wondering of getting around this hurdle.
Thanks!
You have to subclass QWidgetAction and then simply call the addAction to your menu.
Example code for Spin Box Action with a label
class SpinBoxAction : public QWidgetAction {
public:
SpinBoxAction (const QString& title) :
QWidgetAction (NULL) {
QWidget* pWidget = new QWidget (NULL);
QHBoxLayout* pLayout = new QHBoxLayout();
QLabel* pLabel = new QLabel (title); //bug fixed here, pointer was missing
pLayout->addWidget (pLabel);
pSpinBox = new QSpinBox(NULL);
pLayout->addWidget (pSpinBox);
pWidget->setLayout (pLayout);
setDefaultWidget(pWidget);
}
QSpinBox * spinBox () {
return pSpinBox;
}
private:
QSpinBox * pSpinBox;
};
Now simply create it and add it to your menu
SpinBoxAction * spinBoxAction = new SpinBoxAction(tr("Action Title"));
// make a connection
connect(spinBoxAction ->spinBox(), SIGNAL(valueChanged(int)),
this, SLOT(spinboxValueChanged(int)));
// add it to your menu
menu->addAction(spinBoxAction);
QWidgetAction is a QAction that contains a QWidget. You can use this to encapsulate your QComboBox and add it to your menu via QMenu::addAction.
You can always use a QWidget or QFrame as the Menu Widget, then put a QHBoxLayout on it, and insert your QWidgets inside.