Update user dialog in MFC - c++

I want to update a user interface when I clicked a button. However, I'm not using a direct way inside CProjectDlg. I have a CMain class which will handle the operation.
Here is my code:
ProjectDlg.cpp
void CProjectDlg::OnBnClickedButton1()
{
CMain *ptr = new CMain();
ptr->Click();
CString test = m_edit1;
}
Main.cpp
void CMain::Click()
{
CProjecttDlg *ptr = new CProjectDlg();
ptr->m_edit1.SetString(L"This is a test.");
}
In the debug mode, I found the address of m_edit1 is not same. So the function is useless.
I need to pass the same address of m_edit1 to the Click() function. How do I do that?
Thank you.

Each time you click, you create a new dialog.
CProjecttDlg *ptr = new CProjectDlg();
What you must do is to create it just once (maybe at CMain constructor? or the first time click is accessed). To store its value, just make ptr a member of CMain(define in .h, and so on) instead of a local variable.

You have a problem there. You are calling CMain::Click fron a CProjectDlg instance, but create a new instance of CProjectDlg inside CMain::Click, and set the edit box in that new dialog, not in the original one.
I don't know exactly what you are trying to do, but one thing that could work is to pass a pointer to the dialog to the CMain constructor, and then in CMain::Click use it ot set the edit box. Something like this:
//CMain.h
class CMain
{
public:
CMain(CProjectDlg*);
Click();
protected:
CProjecDlg* m_Dlg;
}
// CMain.cpp
CMain::CMain(CProjectDlg* dlg)
{
m_Dlg = dlg;
}
CMain::Click()
{
m_Dlg->m_edit1.SetString(L"This is a test.");
}
Apart from that, I don't know if it would be necessary to create a new instance of CMain every time the user clicks the bottom.
And finally, the possible solution I've provided might work, but it might also not be "correct". Without more details as to what you are trying to do, there's not much more I can help you with, though.

Related

Qt - How to handle memory management for dialogs?

I am running into the following issue:
Users presses "Ctrl+N" which goes into function MainWindow::newAction()
In MainWindow::newAction(), create a QDialog dlg(centralWidget()) and call dlg.exec()
While dlg is open, users pressed "Ctrl+N" again
The result is that dlg never gets deleted (it will only get deleted once centralWidget() gets deleted).
The call stack is something like this:
MainWindow::newAction ()
...
MainWindow::newAction()
I am wondering how to handle this case. I want all of the local dialog variables from the first call to newAction() to be deleted by the time we go into the function newAction() again.
You also can try something like this:
void MainWindow::newAction() {
const auto dialog = new MyDialog(centralWidget());
// When user will close the dialog it will clear itself from memory
connect(dialog, &QDialog::finished, [dialog]() {
dialog->deleteLater();
});
dialog->exec();
}
However, a good move would be to stop user from summoning more QDialogs than a single one, given that this one is a modal dialog(might be a good idea to keep this dialog pointer as a class member and check is it on screen already before calling exec() on it.
If i understood the question right, you want one dialog to be opened and want to delete it before a new dialog request comes in?
If that's the case you can do following:
In MainWindow.h declare QDialog *dlg = nullptr
In your MainWindow.cpp newAction() function you can do following:
void newAction()
{
if(dlg != nullptr)
{
dlg->close();
dlg->deleteLater();
//or
//dlg->destroy(); // this will immediately free memory
}
dlg = new QDialog(centralWidget());
...
//dlg->exec(); // This will automatically make QDialog modal.
dlg->show(); // This will not make a QDialog modal.
}
I hope this will help. Remember QDialogs when displayed with exec() they automatically behave as Modal window. show() will make it non-modal.

How to release memory?

I have Created a simple QT application for my university assignment. What i have done is pop up a new QManinWindow from a Above QMainWindow. When i click a button from the main ui it will pop up a new QMainWindow object (Note Pad)
Note pad is also a QMainWindow object
My Problem is when I'm creating the object it takes some memory from the ram but when I'm closing it (pop up window) memory is not releasing. When each time I'm pressing a button memory is allocated but application does not relese the memory when im closing it. Please check the main screen of the app.
i just want to know how to release that memory. I have tried so many things but nothing worked well.
I have set the closeEvent public on NotePad class and I listen the close event from main object when its get triggered i have deleted the poped up object. But it cause ad unexpected stop.
void MainWindow::on_notePadBtn_clicked()
{
NotePad *notePad = new NotePad(this);
notePad->raise();
notePad->activateWindow();
notePad->show();
}
NotePad::NotePad(QWidget *parent) :QMainWindow(parent),ui(new Ui::NotePad) {
ui->setupUi(this);
this->setWindowTitle("Note Pad");
}
You don't really need to override closeEvent, Qt has Qt::WA_DeleteOnClose attribute, that does exactly what you want, you can use it like this:
//...
NotePad *notePad = new NotePad(this);
notePad->setAttribute(Qt::WA_DeleteOnClose);
notePad->raise();
notePad->activateWindow();
notePad->show();
//...
I'm not familiar with Qt.
But to my understanding if you use the operator new
you must use delete (in a scope where you have access to the pointer created with new).
Object *foo = new Object();
// Do stuff with foo...
delete foo;
// DO NOT use foo from now on.
Hope that helps a bit, maybe. Like I said I'm not familiar with Qt
so if you have doubts about how some features are implemented you should look at the their docs.
(cf: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf §3.7.4p63)

C++, Passing custom class object in wxWidgets

Can someone explain me how to pass a custom class object to another function in wxWidgets? I have a wxDialog class called AddUser which contains a void type OnButtonClick function that creates an object of a custom class "User". How can I pass that object to another OnButtonClick function that is located in Main class?
One important thing to know (in case you don't already) about wxDialog is that it is quite okay to create them on the stack (most wxWidgets windows should be created on the heap).
This means that your dialog instance remains available even after it has been closed by the user pressing "Ok". You can test for user responses by the following code:
... existing method ...
AddUser dialog (this);
if (dialog.ShowModal() == wxID_OK)
{
... process new user ...
}
Because the dialog is still instantiated, you can include a method in your dialog code that returns the new user as follows:
User AddUser::GetUser ()
{
return newUser;
}
However, you should of course be careful where the new user is actually created. For example, if the new user object is created locally in the dialog, then you will need to make a copy of it (as the above example will do). If it is created on the heap (which I wouldn't advise) then you can return a pointer. A third alternative would be to pass a reference to the GetUser method so the dialog method looks like this:
bool AddUser::GetUser (User& user)
{
// Make sure that all fields are valid. Simple example given, but
// should be more complete.
if (TextName->GetValue() != "" && TextSurname->GetValue() != "")
{
user.setName(TextName->GetValue());
user.setSurname(TextSurname->GetValue());
return true;
}
return false;
return newUser;
}
And the call looks like this:
void wxBiblioFrame::OnButAddUserClick(wxCommandEvent& event)
{
AddUser dialog(this);
myUserDialog dialog (this);
myUserClass newUser;
if (dialog.ShowModal() == wxID_OK)
{
if (dialog.GetUser (newUser))
{
... process and store the new user ...
}
else
{
... handle the error ...
}
}
// NOTE: no need to Destroy() the dialog.
}
By the way, unless your user class is huge, I wouldn't be too concerned making copies of the object from an efficiency point of view. Creating and closing the dialog is likely to dwarf any time taken in making a copy.
You can't call an OnClick event and pass something different than the parameters in the event signature. If you need somthing like tis then maybe you should consider reiterating your application's architecture.

MFC: Deleting dynamically created CWnd objects

Lets say in a dialog, we dynamically create a variable number of CWnds... like creating a and registering a CButton every time the user does something/
Some pseudo-code...
class CMyDlg : public CDialog
{
vector<CWnd *> windows;
void onClick()
{
CButton *pButton = new CButton(...);
//do other stuff like position it here
windows.push_back(pButton);
}
}
Do I need to explicitly delete them or will MFC do it? If I have to, would it be in the destructor as normal, or are there any special things to avoid breaking MFC... making sure I don't delete the objects while the HWNDs are still in use for example?
CButton *pButton = new CButton(...);
These are C++ objects, which needs to be deleted explicitly. (Where as Main frame windows and Views are self destructed).
You can refer the detailed answer ( by me) Destroying Window Objects

Showing two windows in Qt4

My friend and I have each created parts of a GUI using Qt 4. They both work independently and I am trying to integrate his form with the my main window. As of now this is the code I am using to try and load his form:
//connect buttons and such
connect(exitbtn, SIGNAL(triggered()),this,SLOT(terminated()));
connect(add, SIGNAL(triggered()),this,SLOT(add_rec()));
void MainWindowImpl::add_rec()
{
//form quits as soon as it loads...?
DialogImpl dia;//name of his form
dia.show();
}
I have included his header file. The program compiles but when I hit the trigger his form loads up for maybe half a second and then closes. Does anyone know what I am doing wrong?
You have almost get it right. This is because the RAII of C++. If you allocate the Dialog on stack, it would be destructed as soon as the function return.
Assuming MainWindowImpl inherits publically from QWidget, you're looking for this:
void MainWindowImpl::add_rec()
{
// passing "this" to the constructor makes sure dialog will be cleaned up.
// Note that DialogImpl will need a constructor that takes a
// QObject* parent parameter.
DialogImpl* dialog = new DialogImpl(this);
dialog->show();
}
Look at the Qt documentation for examples of how the constructors should look.
Apparently QT4 only allows one instance of an object at a time, however pointers are another matter. Change both the main.cpp and what ever your main window to look something like this:
DialogImpl *dia=new DialogImpl;
dia->show();