How to close the main window when a dialog appears - c++

I was making a test program where the MainWindow serves as a login screen. User types in a username and password. If they match what the string is assigned to, then the Dialog appears. If it fails, a QMessageBox appears instead.
What my issue is when I want the Dialog to appear (the main program), I want the Login page to disappear. The Command close(); would just close everything.
Here is the code for the MainWindow.cpp (The Dialog is referenced in the header as a POINTER called mDialog)
void MainWindow::on_pushButton_clicked()
{
if (ui->lineEdit->text() == username)
{
if (ui->lineEdit_2->text() == password)
{
//This is where the Dialog appears
mDialog= new MyDialog(this);
mDialog->show();
}
}
else if (ui->lineEdit->text() != username || ui->lineEdit->text() ==NULL)
{
if (ui->lineEdit_2->text() != password || ui->lineEdit_2->text() == NULL)
{
QMessageBox::warning(this, "Error", "The username or password is incorrect.");
}
}
}
Here is the code for the main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

In Qt if the parent is destroyed, the children also, so if you go to this as a parameter to MyDialog, it will be destroyed. So that it is not destroyed do not pass the parent.
Change mDialog= new MyDialog(this) to mDialog= new MyDialog() and place close() after show().
The function would look like:
...
mDialog= new QDialog();
mDialog->show();
close();
...

I think you should be showing the dialog as the login and the main window as the main program. If login is a success, show main window, not the other way around. Closing the main window is going to close the program.
I have done what you are trying to do. You can do what I said above or another option is to create a login screen in the main window using a QLabel. You can add an image to the Qlabel (a solid color image or anything you like) and make it the size of the window to block the view of the main program. Then you can add your line edits and buttons or anything you want. If login is successful, the image, labels and buttons can be closed to reveal the main program. I checked input using regular expressions.

Use this->close() to close the current window, but in the constructor of MyDialog, don't pass anything to the constructor. By default, the constructor will pass 0 to the parent argument, so as a result, the dialog will not have a parent.

If your main program is the Dialog you can before it have been shown open the login dialog with username/password fields.
Pseudocode for the main function (LoginDialog and MainDialog inherits QDialog):
QApplication a(argc, argv);
LoginDialog lDialog;
lDialog.exec(); // Modal dialog behavior. Stopped at this line while it not closed (QDialog::close())
if (lDialog.getUsername() != username || lDialog.getPassword() != password)
{
return 0;
}
MainDialog mDialog;
mDialog.show();
return a.exec();

You can set window visibility to false.
mainwindow.setVisible(false)

Related

how to switch windows between cpp files? in Qt

I have problem with my small app in Qt framework C++
I have a first window which there's two buttons where you can choose to play music or video. The music button will close the "choose window" and should open "music window" and similarly for video button.
I don't know how to do this... I know a way which I've leant and used but this method I'm going to explain how it doesn't fit to my current issue.
I've created a pointer of that window class in header of choose window and when the music button is clicked, I new the pointer and musicWindow->show(); and hide(); the choose window, this is good but there is a problem:
the new opened music window doesn't have any taskbar icon/thumbnail and when Its minimized there's no way to have that opened again(except wtih alt-tab)
and dont find a way to open it like a complete new window, I just can open all of them at once by using choosWindow.show(); / musicWindow.show(); /... .
I know there must be a way, but I dont even know what topics to search for to get further...
FirstWindow.cpp:
void FirstWindow::on_musicChoose_clicked()
{
//send a signal from here
}
void FirstWindow::on_videoChoose_clicked()
{
//send a signal from here
}
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FirstWindow w;
if(//what condition?)
{
MusicWindow mw;
mw.show();
}
if(//what condition?)
{
VideoWindow vw;
vw.show();
}
return a.exec();
}
I found my answer in Qt Forum:
https://forum.qt.io/topic/68602/child-window-in-taskbar/3
#Radek(Qt Forum): Try passing 0 (zero) as parent when you create them.
FirstWindow.cpp:
void FirstWindow::on_musicChoose_clicked()
{
this->hide();
mw = new MusicWindow(0); // passing nullptr as parent
mw.show();
}
void FirstWindow::on_videoChoose_clicked()
{
this->hide();
vw = new VideoWindow(0); // passing nullptr as parent
vw.show();
}
main.cpp:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FirstDialog w;
w.exec();
return a.exec();
}

Why virtual keyboard does not work with QDialog textbox in Qt?

I make an application for keyboard less device.
I used thisRef for keyboard as virtual keyboard.
I have a dialog in my project that has two textboxes (one of them for enter user name and the other for input password ) with two buttons: OK and Cancel. after Build the project and run ,the press menu button to show menu form, then the dialog appears to check user authenticate. the user should enter data on text box the virtual keyboard .
the virtual keyboard (input panel in thisRef ) appears but the buttons not work.
when I searched I saw this "sounds like you are trying to open another window from the dialog - this is your error. Of course the dialog will stay on top - that is its job."
because the dialog is modal, the virtual keyboard is disable
Is there anyway to edit the dialog or keyboard to work in modal widget?
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include "myinputpanelcontext.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyInputPanelContext *ic= new MyInputPanelContext; ;
a.setInputContext(ic);
MainWindow w;
//w.show();
w.showFullScreen();
w.centralWidget()->releaseKeyboard();
return a.exec();
}
MainWindow.cpp:
MyDialog *d=new MyDialog(this);
d.exec();
It solved:
Modal dialogs are started with exec(), they block the program flow while a nested event loop runs.
Modeless dialogs are started with show(), they do not block the program flow.
From http://www.qtforum.org/article/14285/modeless-dialog.html
I use this code :
MyDialog *d=new MyDialog(this);
d->show();
d->raise();
q->activewindows();
instead of this code:
MyDialog *d=new MyDialog(this);
d.exec();
as the document reference :
A modeless dialog: void EditorWindow::find() {
if (!findDialog) {
> findDialog = new FindDialog(this);
> connect(findDialog, SIGNAL(findNext()), this, SLOT(findNext()));
> } findDialog->show();
> findDialog->raise();
> findDialog->activateWindow(); }
From here

Qt Dialog X Button Override Reject Not Working As Expected

I have been trying to hide a stand alone dialog application when the user hits the typical close button (The one with the X in the corner usually next to the minimize button) I cam across this post:
Qt: How do I handle the event of the user pressing the 'X' (close) button?
which I thought would have my solution, but I get strange behavior when I implement it.
void MyDialog::reject()
{
this->hide()
}
When I hit the X Button the whole application closes (the process disappears) which is not what I want. Since my gui spawns with a command line, I setup a test system where I can tell my dialog to hide via a text command where I call the same 'this->hide()' instruction, and everything works fine. The dialog hides and then shows back up when I tell it to show.
Any ideas why the reject method is closing my app completely even when I don't explicitly tell it to?
Override the virtual function "virtual void closeEvent(QCloseEvent * e)" in your dialog class. The code comment will explain in detail.
Dialog::Dialog(QWidget *parent) :QDialog(parent), ui(new Ui::Dialog){
ui->setupUi(this);
}
Dialog::~Dialog(){
delete ui;
}
//SLOT
void Dialog::fnShow(){
//Show the dialog
this->show();
}
void Dialog::closeEvent(QCloseEvent *e){
QMessageBox::StandardButton resBtn = QMessageBox::question( this, "APP_NAME",
tr("Are you sure?\n"),
QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes,
QMessageBox::Yes);
if (resBtn != QMessageBox::Yes){
//Hiding the dialog when the close button clicked
this->hide();
//event ignored
e->ignore();
//Testing. To show the dialog again after 2 seconds
QTimer *qtimer = new QTimer(this);
qtimer->singleShot(2000,this,SLOT(fnShow()));
qtimer->deleteLater();
}
//below code is for understanding
//as by default it is e->accept();
else{
//close forever
e->accept();
}
}

Connect to WebSocket server from Qt UI with Echo Client Example

I'm using Websocket Echo Server Example in CLI and it works fine. I'm trying to connect to this server from my Qt GUI project. I have MainWindow class with an appropriate slot
void MainWindow::on_pushButton_clicked()
{
qDebug() << "Push btn clicked";
EchoClient client(QUrl(QStringLiteral("ws://localhost:1234")));
}
and EchoClient files from CLI Websocket Echo Client Example.
The main problem is that that I can't connect to the server when I push button on the form. However, I see debug message "Push btn clicked". It is supposed to be printed "Hello, world!". But nothing happens, no errors. Even signal void EchoClient::onConnected() is not fired.
But if I move EchoClient client(QUrl(QStringLiteral("ws://localhost:1234"))); to main.cpp it connects:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
EchoClient client(QUrl(QStringLiteral("ws://localhost:1234")));
return a.exec();
}
I am completely new in C++ and Qt.
Why this happens? Is it something with processing threads in UI? What should I know?
Qt 5.4.
inside your on_pushButton_clicked() function you are creating the EchoClient (which is asynchronous) in the stack of the function. As soon as the function exits, the EchoClient object is destroyed from the stack.
You can think about different solutions like creating a private field in the MainWindow class
private EchoClient *client;
then set it to null in the MainWindow constructor:
this->client = NULL;
and only at this point doing something like this in your click() routine:
void MainWindow::on_pushButton_clicked()
{
qDebug() << "Push btn clicked";
if (this->client == NULL)
{
this->client = new EchoClient(QUrl(QStringLiteral("ws://localhost:1234")));
}
else
qWarning() << "Carefull, the client is already running";
}
Then it is up to you taking care of the like cycle of the client object you have created.
Probably you have to think when you want to destroy it, probably via a "reset" button routine.
I suggest this reading: http://doc.qt.io/qt-4.8/qapplication.html#details

QDialog not closing right away when pressing the X, how to make it NOT on top?

I open QDialog window from QMainWindow. Now when I press the QDialog window
its not always closing in the first press - I need to press few times (3-4) to close it .
I have closeEvent slot that has simple event->accept(); inside it.
This is how I call the QDialog from the main window:
void MyManager::DialogContainerOpen(type t)
{
if(pMyDialogContainer == NULL)
{
pMyDialogContainer = new MyDialogContainer();
}
int returnVal = QDialog::Rejected;
if(!m_bContainer)
{
m_bContainer = true;
int returnVal = pMyDialogContainer->exec();
if(returnVal != QDialog::Accepted ) {
m_bContainer = false;
}
}
}
This is the first problem.
The second problem is how do i set the QDialog windows NOT to be allays on top? (I don’t want it to block the parent window.
UPDATE
well i found out that the function from the MainWindow that showing the contexMenu
and inside it has the connect single/slot is keeps to invoke so i just used the disconnect
i dont know if its the best sulotion but its working.
now i juat have the final problem .
here is the code i hope its ok
void MainWindowContainer::ShowContextMenu(const QPoint& pos) // this is a slot
{
QModelIndex modelIndx;
QPoint globalPos = ui.treeView_mainwindow->mapToGlobal(pos);
bool b1 = connect(OpenAction, SIGNAL(triggered()),m_SignalMapper, SLOT(map()) );
m_SignalMapper->setMapping(OpenAction,voidID);
bool b2 = connect(m_SignalMapper, SIGNAL(mapped(QString)), this, SLOT(OpenWin(QString)));
QAction* selectedItem = ContextMenu.exec(globalPos);
}
void MainWindowContainer::OpenWin(QString gid)
{
//disconnect(sender0, SIGNAL(overflow()),receiver1, SLOT(handleMathError()));
disconnect(m_SignalMapper, SIGNAL(mapped(QString)),this, SLOT(OpenWin(QString)));
disconnect(OpenAction,SIGNAL(triggered()),m_SignalMapper, SLOT(map()));
....
....
}
For your second question, the term you are looking for is modal vs modeless dialogs. The QDialog documentation tells exactly how you create non-modal dialogs:
Modeless dialogs are displayed using show(), which returns control to the caller immediately.
i.e. don't use exec() as that will make a modal dialog (which blocks the parent).
You should not connect the same signal/slot more than once unless you want the action run multiple times. All you need to do is to connect the QAction's signal to the slot once. This is usually done in the constructor (or a dedicated function called from the constructor) where you create the action.