QDialogButtonBox buttons not responding - c++

When I run the following function, the dialog shows with everything in place. The problem is that the buttons won't connect. OK and Cancel do not response to mouse clicks.
void MainWindow::initializeBOX(){
QDialog dlg;
QVBoxLayout la(&dlg);
QLineEdit ed;
la.addWidget(&ed);
//QDialogButtonBox bb(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
//btnbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
la.addWidget(buttonBox);
dlg.setLayout(&la);
if(dlg.exec() == QDialog::Accepted)
{
mTabWidget->setTabText(0, ed.text());
}
}
At runtime, an error in the cmd shows: No such slots as accept() and reject().

You are specifying the wrong receiver in the connection. It's the dialog that has the accept() and reject() slots, not the main window (i.e. this).
So, instead, you just need:
connect(buttonBox, SIGNAL(accepted()), &dlg, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), &dlg, SLOT(reject()));
And now when you click the buttons, the dialog will close, and exec() will return either QDialog::Accepted for OK, or QDialog::Rejected for Cancel.

Related

Qt - connect menuBar and QWidget

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();
});

Qt, QDialog buttons not Respondig

The dialog opens with two buttons, OK and Cancel. None of the buttons responds to user click. I have to press the X on the top right to cancel the dialog.
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == mTabWidget && event->type() == QEvent::MouseButtonDblClick)
{
// query and set tab(s) names
QTabWidget *tab = qobject_cast<QTabWidget *>(obj);
if(tab)
{
QDialog dlg;
QVBoxLayout la(&dlg);
QLineEdit ed;
la.addWidget(&ed);
QDialogButtonBox bb(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
la.addWidget(&bb);
dlg.setLayout(&la);
if(dlg.exec() == QDialog::Accepted)
{
tab->setTabText(0, ed.text());
return true;
}
}
}
// Standard event processing
return QObject::eventFilter(obj, event);
}
Am I missing any connect() line or signals? I tried to read the Qt documentation, but from what I understood, calling QDialogButtonBox::OK gets processed as Accepted.
UPDATE :
New Dialog Function
OK, i have created a new function that takes care of the Dialog box, i am calling it from the event function. it is still not responding, now on the terminal, i see an error that says, : no such slot MainWindow::accept() and another for reject. I know that i have no slots for these two in the .h file. i tried to find how to build the slots but i couldnt, any help would be great. thank you
void MainWindow::initializeBOX()
{
QDialog dlg;
QVBoxLayout la(&dlg);
QLineEdit ed;
la.addWidget(&ed);
//QDialogButtonBox bb(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
//btnbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
la.addWidget(buttonBox);
dlg.setLayout(&la);
if(dlg.exec() == QDialog::Accepted)
{
mTabWidget->setTabText(0, ed.text());
}
}
Rather than launching the dialog from event filer you should trap QWidget::mouseDoubleClickEvent by overloading that virtual function in your code. And as long as it is a callback already you can do more stuff immediately from there including the dialog. Or maybe send the signal to slot that does the dialog (a bit cleaner). I would do the signal from mouseDoubleClickEvent event handler and make the parent QWidget::mouseDoubleClickEvent to consume the event to avoid possible complications especially when porting the code to other platform.
Event filters are for non-standard event processing. There is nothing non-standard in your case.

Not able to connect aboutToQuit signal from QApplication

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();
}

QDialog::accepted() slot not working

I am trying to implement a signal-slot system for a QDialog. After a Google search, I've got this question on Stack Overflow. That answer looks promising, so I tried to use it. I get no error, but the slot doesn't work. Below is my code:
newactivity.cpp
// in the QDialog constructor
QObject::connect(this->ui.createBtn, SIGNAL(clicked()), this, SLOT(accept()));
QObject::connect(this->ui.cancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
void newActivity::accept() {
QDialog::accept(); // to close the dialog and return 1
}
void newActivity::reject() {
QDialog::reject(); // to close the dialog and return 0
}
schedule.cpp
void Schedule::on_actionNew_Activity_triggered() {
newActivity *newActivityWnd = new newActivity(this, Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
newActivityWnd->exec();
QObject::connect(newActivityWnd, SIGNAL(accepted()), this, SLOT(on_activityCreated()));
}
void Schedule::on_activityCreated() {
this->ui.timeLine->hide();
}
Here is my dialog:
Nothing happens when I press the Create button on New activity dialog. Where am I wrong?
I suppose you reorder the code in schedule.cpp as:
void Schedule::on_actionNew_Activity_triggered() {
newActivity *newActivityWnd = new newActivity(this, Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
QObject::connect(newActivityWnd, SIGNAL(accepted()), this, SLOT(on_activityCreated()));
newActivityWnd->exec();
}
Does this solve your problem?

how to use mousePressEvent on QPushButtons

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