how to modify the ui from outside the instance that created the ui?
-
Hi!
I want to insert in a
textEdit
that MyObject was created, like this:self.ui.textEdit.insertHtml('MyObject was created<br>')
But how I change the
textEdit
from outside the instance that creates the ui?For example: if I want to change the
textEdit
from MyObject, should I do this?:class MyObject: def __init__(self): MainWindow.ui.textEdit.insertHtml('An Obj was created<br>')
or this?:
class MyObject: def __init__(self, MainWindow): # <===I put MainWindow here MainWindow.ui.textEdit.insertHtml('An Obj was created<br>')
or this?:
class MyObject(MainWindow): # <===I put MainWindow here def __init__(self): self.ui.textEdit.insertHtml('An Obj was created<br>') # <===I put self here
(MainWindow is the class that creates the ui)
As you can see the problem is that I don't know how to reference the instance of MainWindow from MyObject
This is how the overall code looks like if you want to know:
*lots of imports* *lots of imports* *lots of imports* class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) ... ... ... class MyObject (): def __init__(self): MainWindow.ui.textEdit.insertHtml('An Obj was created<br>') ... ... ... if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
Thanks!
-
Hi!
I want to insert in a
textEdit
that MyObject was created, like this:self.ui.textEdit.insertHtml('MyObject was created<br>')
But how I change the
textEdit
from outside the instance that creates the ui?For example: if I want to change the
textEdit
from MyObject, should I do this?:class MyObject: def __init__(self): MainWindow.ui.textEdit.insertHtml('An Obj was created<br>')
or this?:
class MyObject: def __init__(self, MainWindow): # <===I put MainWindow here MainWindow.ui.textEdit.insertHtml('An Obj was created<br>')
or this?:
class MyObject(MainWindow): # <===I put MainWindow here def __init__(self): self.ui.textEdit.insertHtml('An Obj was created<br>') # <===I put self here
(MainWindow is the class that creates the ui)
As you can see the problem is that I don't know how to reference the instance of MainWindow from MyObject
This is how the overall code looks like if you want to know:
*lots of imports* *lots of imports* *lots of imports* class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) ... ... ... class MyObject (): def __init__(self): MainWindow.ui.textEdit.insertHtml('An Obj was created<br>') ... ... ... if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
Thanks!
@adrian88888888 said in how to modify the ui from outside the instance that created the ui?:
For example: if I want to change the textEdit from MyObject, should I do this?:
No you should not.
You should instead define an interface to set the text in the class where this UI is located.class MainWindow... def setText(self, text): self.ui.textEdit.insertHtml(text)
And then use this interface (setText in my example) from other classes to change the text. Never expose internal implementation details of a class to the outside world!
In Qt you also could use signals slots for that if it makes sense.
-
@adrian88888888 said in how to modify the ui from outside the instance that created the ui?:
For example: if I want to change the textEdit from MyObject, should I do this?:
No you should not.
You should instead define an interface to set the text in the class where this UI is located.class MainWindow... def setText(self, text): self.ui.textEdit.insertHtml(text)
And then use this interface (setText in my example) from other classes to change the text. Never expose internal implementation details of a class to the outside world!
In Qt you also could use signals slots for that if it makes sense.
@jsulm said in how to modify the ui from outside the instance that created the ui?:
And then use this interface (setText in my example) from other classes to change the text.
I cannot imagine another class which would/should need access to an application's
QMainWindow
. It would either require passing the main window instance as a parameter, or finding the single top-level main window instance viaQApplication::topLevelWidgets()
, or casting aparent
to theMainWindow
class. None of which are recommended, or should be necessary.If the OP really wants some other class to cause the main window to alter, either the main window should fetch the result from the other class or the other class should send a signal which the main window has slotted onto.
Or, the architecture should be rethought, it's not clear why this other class would even need to do this.
I trust @jsulm will agree with this approach :)
-
@jsulm said in how to modify the ui from outside the instance that created the ui?:
And then use this interface (setText in my example) from other classes to change the text.
I cannot imagine another class which would/should need access to an application's
QMainWindow
. It would either require passing the main window instance as a parameter, or finding the single top-level main window instance viaQApplication::topLevelWidgets()
, or casting aparent
to theMainWindow
class. None of which are recommended, or should be necessary.If the OP really wants some other class to cause the main window to alter, either the main window should fetch the result from the other class or the other class should send a signal which the main window has slotted onto.
Or, the architecture should be rethought, it's not clear why this other class would even need to do this.
I trust @jsulm will agree with this approach :)
-
@JonB My suggestion isn't restricted to this specific case. It is more general.
In this specific case signals/slots would help to decouple main window and other classes even more. -
@jsulm and @JonB this is really useful to me because i didn't know about the concept of decoupling just a minute ago
My problem its more general then:
I have 750 objects created from the same class, his attributes are stabilized by like 10 modules in the constructor
I want to work with one object at a time with a uiSo I want from the ui to:
-see the attributes
-edit them
-apply the edit
-repeat the process with the next objectAnd i want to show on what step of the process i am in a
textEdit
, for example:log('Analyzing object number X...') log('His name its not valid...') log('Assigning automatically a new name...') log('Asking to the user to define his color with the ui...')
My approach was wrong because of coupling
What's the right way then?
Because if for example I use the class of the ui to know about the attributes
of each object to show/edit them, then i'm coupling the classes right?, then
that's not the solution, I guess?The 2 classes have to interact somehow
-
Hi,
What are these 750 objects ?
From the looks of it, you could store these various settings in a model and then use QDataWidgetMapper to navigate through the model and do the edition.
-
@jsulm and @JonB this is really useful to me because i didn't know about the concept of decoupling just a minute ago
My problem its more general then:
I have 750 objects created from the same class, his attributes are stabilized by like 10 modules in the constructor
I want to work with one object at a time with a uiSo I want from the ui to:
-see the attributes
-edit them
-apply the edit
-repeat the process with the next objectAnd i want to show on what step of the process i am in a
textEdit
, for example:log('Analyzing object number X...') log('His name its not valid...') log('Assigning automatically a new name...') log('Asking to the user to define his color with the ui...')
My approach was wrong because of coupling
What's the right way then?
Because if for example I use the class of the ui to know about the attributes
of each object to show/edit them, then i'm coupling the classes right?, then
that's not the solution, I guess?The 2 classes have to interact somehow
@adrian88888888
First, always follow @SGaist's advice. You need to think through the big picture of whatever you're trying to achieve.For the earlier, specific question of showing something from elsewhere in the main window. If you have some action to report from somewhere else in code, instead of having that access the main window directly and set text, think about having the code emit a signal, with a parameter conveying what has happened. The main window connects a slot to that, and updates the text appropriately when it gets called. Qt code is all about signals & slots.
-
Okey now i'm hesitating about my general approach
Can you tell me if my approach its the best?I'm a music producer, I have 750 song projects in 750 folders, each folder has an id number, readme files, etc(caotic stuff)
So I have to order this caos
So I figured why not make 750 objects and each one represents a project, in their creation i gatter the data and make them their attributes, like:
attributes:
-his directory
-list of thing to do with that project(todos basically)
-i need to know which projects are good and which are bad, so each project has that written somewhere, i want that as an attribute
-the time it was created
-and more hard to explain thingsThen I process the data/attributes with the help of the Qt gui and scripts, I put the data/attributes in a database, and this chaos should be useful again
Should I keep going in my direction and learn about signals/slots making the porjectObject communicate with the UI?, or should I use
QDataWidgetMapper
like @SGaist suggested? or there's something else? -
Ok, so in fact you want to build a parser to create a database, correct ?
Are all these musical project folders stored in one directory ?
Depending on that, there might be several ways to write your application.Take the time to learn both signals and slots and model views. They are not mutually exclusive, quite the contrary.
You should take the time as well to look at Qt's SQL module.
-
Okey now i'm hesitating about my general approach
Can you tell me if my approach its the best?I'm a music producer, I have 750 song projects in 750 folders, each folder has an id number, readme files, etc(caotic stuff)
So I have to order this caos
So I figured why not make 750 objects and each one represents a project, in their creation i gatter the data and make them their attributes, like:
attributes:
-his directory
-list of thing to do with that project(todos basically)
-i need to know which projects are good and which are bad, so each project has that written somewhere, i want that as an attribute
-the time it was created
-and more hard to explain thingsThen I process the data/attributes with the help of the Qt gui and scripts, I put the data/attributes in a database, and this chaos should be useful again
Should I keep going in my direction and learn about signals/slots making the porjectObject communicate with the UI?, or should I use
QDataWidgetMapper
like @SGaist suggested? or there's something else?@adrian88888888
They are not either-ors. You will end up using signals & slots soon enough with Qt. The issue of sending a message to the main window is a small detail.You will want to create a model for your song projects. Think rows for the projects, "attributes" exposed as columns. You can then use Qt's
QDataWidgetMapper
to allow the user to view, and edit if desired, one project at a time, with all its attributes as widgets. Read about Qt's Model/View architecture first: https://doc.qt.io/qt-5/model-view-programming.html & https://doc.qt.io/qt-5/modelview.html . -
@JonB making a model of the 750 items make sense if there's data, but there's some data, the rest has to be gathered
also when the program gets a piece of data that can't figure out what is(using RegExp), then it has to be shown to the user(using de ui) so it can be decided manually what is
so i'm using the ui to make half of the data, so then i can make the model/data-base
@SGaist i just googled what is a 'parser', i didn't know that this was a common problem, i'm so newbie, I would have said it from the start...
and yes, the projects are inside the same directory
now i know what's the next step, learning about signals/slots and QDataWidgetMapper, i know already about model views
Thanks!