[Merged] Inheriting Ui::MainWindow to add QListWidgetItem to a give ListWidget
Ok this is a rather difficult problem i have run into. I am attempting to inherit the ui to a given class. From this class i have functions that add list items to a list located on the parent widget. I can achieve this with no problem. Once I implement however, it throws a segFault. any thoughts? here are some code snipets.
from my header
- class MedicationButtonEventHandler : QWidget , public Ui::MainForm
- virtual ~MedicationButtonEventHandler();
- static MedicationButtonEventHandler* GetInstance();
from my cpp
- QListWidgetItem* MedicationButtonEventHandler::Medication_Add_Clicked()
- Ui::MainForm *ui = new Ui::MainForm;
- ui->txt_Medicaiton_MedicationName->text()+ " - "+
- ui->cmb_Medication_Dosage->currentText()+ " - " +
- ui->cmb_Medication_Quantity->currentText()+" - " +
- ui->cmb_Medication_Method->currentText()+ " - " +
- ui->txt_Medication_Frequency->text()+" - " +"Date Started: "+
- ui->txt_Medication_DateStarted->text()+ " Date Modified: " +
- ui->txt_Medication_DateModified->text()+ " Date Stopped: " +
- ui->txt_Medication_DateStopped->text()+ " - " +
- ui->txt_Medication_PrescribingDoctor->text()+ " - " +
- ui->txt_Medication_Pharmacy->text()+ " - " +
- ui->txt_Medication_PharmacyPhone->text()+ " - " +
- ui->txt_Medication_PrescriptionNumber->text()+ " - " +
- return listItem;
- delete listItem;
- delete ui;
when i call this function to test it it segfaults. I know it is recommended that i inherit ui privately, but i need to be able to actually change attributes of the ui. Thanks for any help.
edit: code highlighted / Denis Kormalev
The segfault is beacause you did not call
Also, there are some more mistakes:
- you do not have a constructor for your class. This is a must have one, and you mast call the base class constructor (QWidget in your case) with the parent. Otherwise you will not have the parent-child relationship and QObject does not delete your objects
- you usually setup the UI in the constructor with that mentioned setupUi() method
- in your case, every time you call MedicationButtonEventHandler::Medication_Add_Clicked() you construct an new ui. If you call it 10 times you end up with 10 ui instances.
Right I realize the 10 ui instances part, as far as a constructor and such i do have one, i did not include my entire header file just where i was inheriting. I dont want it to be a child of anything, I want to be able to call this function on some click event, and add an item to an already existing widget from the actual UI designer. I guess im not fully understanding the need to call setupUI when im not trying to create a new one. I am relatively new to QT and as such i do not know all the ins and outs yet.
Wether the constructor is private does not matter. At the time your widget is constructed, it should be constructed correctly and complete.
As far as I understood:
- This class is a widget (as it inherits from QWidget)
- This is a singleton (which does not matter in our case)
- You have kind of button and/or action that you click on and in a slot connected to the clicked() or triggered() signal you want to create a new list item that is added to your list view
If that is true:
- call setupUi(this) in the constructor
- no need to create an instance of the Ui class with new (line 3 in your cpp), as your Widget already inherits this class! Call the ui members without “ui->”
- In your slot, create the list item and add it to the list view. If you setup the ui in the constructor and if you have called setupUi() you won’t get a segmentation fault.
The QWidget was a mistake from something i had tried early on. Its not a widgetclass at all. I actually inherit QObject. As far as actually setting the ui the way you described, does not work either.As far as my design, i simply want to be able to handle function definitions outside of the main form to prevent it from being 8000 lines. So to do this i need to abstract out the Ui aspect of much of it( the things that need to be dynamically generated based on user input). So I simply want a function that, when called, will add a new listitem to an already existing listwidget ( located in ui_MainForm.h). The code works if moved into MainForm. I just cant seem to get the interface to work properly. I should be able to simply inherit from the Mainform( which will carry all of its child widgets with it) and make whatever changes i need to make as needed. At this point I am not even concerned with the slots and signals. I just wish to call a function located outside of Mainform that changes mainform itself( or its children). Does that better explain things?
Sorry, I don’t understand what you’re trying to do. It sounds like you’re doing it over complicated. If your business logic has 8000 lines, it hat 8000 lines of code – regardles if it is in one file or split over 20.
Adding an item is in my opinion a function that belongs to the list widget class (reps. the form that does contain the list widget). You should add method (probably as a slot) that you call with the relevant data and let the method create the list view item. That also has the advantage that you can change your implementation afterwards without the need to change all your other code.
Regarding the UI (classes):
A UI class generated with uic from a .ui file only does make sense and is functionable when you marry it with a QWidget, that’s what setupUi() is for. If you don’t call that, your UI is useless.
I’d suggest you make yourself comfortable with the principles of the uic generated classes first. Use Chapter Using a Designer UI File in Your Application [doc.qt.nokia.com] of Qt Designer documentation as a starting point
And as an advice: Make it work correctly in the first place and do the optimizations afterwards. If you have a working application – made straight forward – it is often much easier to “beautify” it later.
I would recommend keeping the UI class small by using signals, slots and accessors. Add signals for all the ui actions that are of interest and connect them to other objects implementing the business logic. Those can in turn trigger slots in the UI to trigger the changes you want. That way the internals of the UI stay in one class and you will not need to fix up code all over the place when you decide to rework the UI.
I’m sure it can be done the way you intend to do it. But sometimes one just screws up everything. I’ve been bitten often enough :-) I usually start from scratch then.
Regarding your problem:
Of course you can create a list widget item with new in a separate class and add it to the ui of another class. But that couples the two classes tightly, which is not what you want most times, since one class needs to know the internals of the other. Maybe you decide to drop QListWidget in favor of QListView and specially design item model. You would have to change all your code!
It’s usually better to send messages to the other class and ask it to do the desired task (using signals/slots in Qt). Since the actual implementation is not public in this case, you easily could do the refactoring I mentioned in the paragraph before.
Give it a try and you will get beautiful and easy to write and maintainable code :-)
Pure answer is that U call methods on uninitialised pointers.
Any form you create, throwing the widgets in the designer – just a collection of widgets. Try to open ui file in a text editor ;) ( But better don’t save it in editor )
So, when UIC eats form file it produces a Collection class: set of pointers with two methods – setupUi( Parent* ) and retranslateUi. Parent is QWidget in common case.
setupUI is a key! It creates and inits real widgets and sets them Parent as parent.
No setupUi – no real objects and then U’ll get segfault in ui->txt_Medicaiton_MedicationName->text().
See qt documentation [doc.qt.nokia.com]
And Yes – UR code is strange
- return listItem;
- delete listItem;
- delete ui;
Do U catch that last three rows never runs?