PDA

View Full Version : MVC problem parameter handover



Basti1990
21st September 2016, 17:50
Hello forum

I tries for the first time at the Model View Controller programming.

I create three classes one for the logic, one for the Gui
and one for the controlling.

But i have a problem by the parameter handover in the logic class.

The application crashed after click button.

My test programm.

Header:


#ifndef LOGIC_H
#define LOGIC_H

#include <QDebug>
#include "gui.h"

class Gui;

class logic
{

Gui *testgui;

public:
logic(Gui *myGui);

void writeTEST();
};

#endif // LOGIC_H

CPP:


#include "logic.h"


logic::logic(Gui *myGui)
{
testgui = myGui;
}

void logic::writeTEST()
{
testgui->testTE->setText("test"); //application crashed
//testgui->testTE->setText("test"); //application run if it comment out
}


Since the proplem is unmistakable by the function call exist.
I don't to see the wood for the trees.


I hope anybody can help me.

I do apologize for my bad english

best regards

Basti1990

anda_skoa
21st September 2016, 21:10
Where do you create the logic object?
Do you pass a valid Gui object to its constructor?

Cheers,
_

d_stranz
21st September 2016, 22:21
In your code, you do not create an instance of a "logic" object anywhere. You declare a pointer to a logic instance in a variable named "l", but it is never initialized. Likewise, since you never create a logic class instance, the "testgui" member variable is never assigned to anything. So you make a call through an uninitialized pointer to a logic class member function, which then tries to make another call through an uninitialized pointer to a GUI class instance.

When you comment out the line you indicated, it is only an accident that your program doesn't crash there, because the "l" pointer doesn't point to anything real (it is uninitialized), but then it isn't executing any code either. When you uncomment that line, your program crashes because now you are trying to use another bad pointer to do something and that's more than the runtime can deal with.

Basti1990
22nd September 2016, 17:04
hello,

thanks for the fast replies.

Now i know what i must to do on weekend.

I'll report if i have solved my problem.

Best regards

Basti1990

d_stranz
22nd September 2016, 18:00
While you are learning this weekend, you should also read about "encapsulation". You have made your QPushButton and other GUI elements "public" members of your GUI class, and you then access them in another class. It is a bad design to expose member variables as public. They should be private, and if you need access to their settings, you provide member functions (or Qt slots and signals) so you can set their value or be notified when the value changes.

It is hard to implement pure MVC using Qt, because the View and Controller parts are usually combined into a class combined from QWidget. For example, QPushButton has a visual appearance on screen (the View part) but also has a Controller part because it handles mouse and keyboard events internally.

However, Qt's slots and signals -do- give you a way to implement MVC at a higher level. Your QWidget classes can provide you with abstractions - for example, QFileDialog has a signal that tells you when a file has been selected. You don't really care how QFileDialog does that on the inside (for example, by selecting a file from a list and then clicking an OK button), what your app cares about is that the user chose a file to open. By implementing a slot that responds to QFileDialog's signal, you can get the name of the file and open it. You could also completely replace QFileDialog with something else, as long as the new widget emits a signal that you can connect to the same slot.

So in your case, you should not create a "logic" object that requires a GUI pointer in order to work. Instead, "logic" should have signals and slots that can be connected (in main() or QMainWindow, or somewhere else) to slots and signals of some other classes. "logic" does not care what those classes are, just that when it receives a signal to do something from a class it is connected to, it does the right thing. Likewise, when "logic" changes its state, it should emit a signal that says so. It doesn't care if anyone is listening, it just does what it is supposed to do.

Basti1990
24th September 2016, 15:49
hello d_stranz,

thanks for your reply.
The Information are very interessting.

You mean i should remove the MVC class
and integrate it on Gui and Logic class.

I'll splite the MVC class
and integrated it on the both another classes.

Like the picture:

12123

Or mean you another thing.

best regards

Basti1990


Ps. The membervariable is only public for testing.

d_stranz
24th September 2016, 18:21
Like the picture

Yes, I think that in general this is the way many Qt programs are implemented. The logic rules are separate from the GUI, and each side "talks" to the other side using signals and slots.

It helps to make names for signals and slots that have a meaning for the way they are used. For example, you might write a signal for the GUI side called "buttonXClicked()". On the logic side, you write a slot called "performActionX()". (And not called "onButtonXClicked()"). The logic side does not care what happened on the GUI side, it just knows that something wants it to execute "actionX". Likewise, on the GUI side, it does not know what will happen when the user clicks "buttonX", it just knows that when it happens, it need to emit the signal.

This is the way many parts of Qt work; in the Item / Views architecture, the "logic" part is a QAbstractItemModel. It stores data and emits certain signals when the data changes. On the GUI side is the QAbstractItemView. It displays the contents of the model, and will change the display in response to the model's signals.