[solved] Newb to child parent forms and how to access the ui elements of child forms



  • I made a second form with it's own menu :)

    and got it to .show()

    but I can't seem to access it's plainTextBox.

    I've heard a few suggestions from accessing it during constructor call.

    but I still wouldn't know how to access it's ui elements.

    I read it might have something to do with child parent relationships, as stated here:

    http://stackoverflow.com/questions/1946046/accessing-the-child-ui-elements-in-a-qt-ui

    Call children() on the top level widget instance.

    Assuming your top level widget is called 'tlWidget':

    myUI->tlWidget->children()

    but I'm new to qt... so I don't know

    Here's code that did work when I created a new form automatically:
    @
    QWidget* win = new QWidget();
    QVBoxLayout* layout = new QVBoxLayout(win);
    QPlainTextEdit* plainTextEditPatchOutput = new QPlainTextEdit();
    layout->addWidget(plainTextEditPatchOutput);

    //Load up patch file into a string
    QString strPatch = dmp.patch_toText(dmp.patch_make(str1, str2));
    QTextStream out(&strPatch);
    plainTextEditPatchOutput->setStyleSheet("font: 9pt "Courier";");
    plainTextEditPatchOutput->setLineWrapMode(QPlainTextEdit::NoWrap);

    //load patch file into plainTextEdit.
    plainTextEditPatchOutput->setPlainText(out.readAll());

    //show window with patch file loaded
    win->show();
    @

    but

    here's the code I want to work with now that has a plainTextBoxOutPatch QPlainTextBox.

    @
    mMyNewWindow = new PatchOutputWindow(); // Be sure to destroy your window somewhere
    mMyNewWindow->show();

    QString strPatch = dmp.patch_toText(dmp.patch_make(str1, str2));
    QTextStream out(&strPatch);

    //mMyNewWindow->setPl

    //ui->plainTextEditLeft->setPlainText(in.readAll());
    @

    the last two commented sections are what I've tried.

    I haven't found any good reliable tutorials that describe form creation and accessing forms from the mainwindow form. they all describe different methods. What I did was create a form using the ui form editor and then called it as you see above. Now I just want to access the objects on the form like I do with mainwindow (which is actually diffmatchpatch.cpp). By calling ui->

    Update
    I think I may have an answer here

    http://www.thedazzlersinc.com/source/2012/06/04/qt-show-child-window-from-parent-vice-versa/

    [edit added missing coding tags @ SGaist]



  • -btw, I have no idea how to edit my post to make the code more readable, I tried 3 times. I don't see a code formatting button in the editor.-



  • following a tutorial of Inheritance Approach:

    http://qt-project.org/doc/qt-5/designer-using-a-ui-file.html#the-single-inheritance-approach

    I made an experimental branch on github showcasing the specific changes.

    https://github.com/thistleknot/DiffMatchPatch/commit/b0a7eaede6838916a3dda3b2d652c4b484ba4990

    It compiles, but I still don't know how to access it as

    uiOutput->

    what's missing is diffmatchpatch.cpp line 156

    uiOutput-> doesn't seem to do anything

    I made sure I did a private member var in my diffpatcmatch.h (basically my mainwindow)Ui::PatchOutputWindow *uiOutput;

    I have a plainTextEdit on the uiOutput (patchOutputWindow) interface I'm trying to port a QString to. I was hoping to access it in a fashion similar to ui->.

    That form specifically (uiOutput) has a menubar that I specifically desire, and so I created a form first using the form editor, and was trying to import it as a new window/form into my project.

    Alternatively I could go with a Tabbed window system. That way I wouldn't have to figure out how to implement these new windows so I can gain access to a pre-made form.


  • Lifetime Qt Champion

    Hi,

    In good written widgets, child widgets don't know anything about their parent. They provide getter and setters for the internal part they allow to modify. If a parent widget needs to react to something happening inside a child widget, it should connect to a signal emitted by the child widget.

    So if you want to update the content of a QPlainTextEdit, add a setter in your container widget e.g. DiffMatchPatchWidget::setPatchContent(const QString& patchFilePath); and in that method, update your ui->myPlainTextEdit

    Hope it helps



  • what about a signal emitted by the parent widget?

    I have a menu drop down where i'm trying to submit a compute, patch algorithm that dumps to a plainTextEdit, but the plainTextEdit I wanted in a new window, and then the option to save it. It's due to the fact that I'm working with multiple documents of similar nature that I need a new window so a person using the app doesn't get confused (even though it's a patch file vs raw txt data).

    I think I see what you mean. If a parent needs to react...

    In this case the child needs to react... so the child has a getter function.

    I don't know why... but I'm used to calling them member accessor functions. Maybe UML?



  • I'm still kind of lost. I'm not trying to update the mainwindow or diffmatchpatch.cpp at all, I'm trying to update patchoutputwindow.cpp with a save slot from diffmatchpatch.cpp. So it's the parent window signalling the child window. So... I would just setup a public function that returns a QString? Then this member function is available by invoking the object and it's object.<function name>?



  • Yeah, i'm completely lost.

    I've been working on this all day. My code worked before by pushing objects to a new window that was locally created so I had no issues with encapsulation. But now...

    I tried reading this article and implementing it

    http://qt-project.org/doc/qt-5/signalsandslots.html

    but got stuck here:

    Counter a, b;
    QObject::connect(&a, &Counter::valueChanged,
                     &b, &Counter::setValue);
    
    a.setValue(12);     // a.value() == 12, b.value() == 12
    b.setValue(48);     // a.value() == 12, b.value() == 48
    

    Here's my code (compiles)

    https://github.com/thistleknot/DiffMatchPatch/commit/b0a7eaede6838916a3dda3b2d652c4b484ba4990

    I'm basically trying to emit a QString from one form to another form.





  • I got it by creating a public function on the receiving form:

    @
    void setOutputWindowText(QString);

    void PatchOutputWindow::setOutputWindowText(QString outputString) {
    ui->plainTextEditPatchOutput->setPlainText(outputString);
    }
    @

    and calling it

    @
    diff_match_patch dmp;

    QString str1 = ui->plainTextEditLeft->toPlainText();
    QString str2 = ui->plainTextEditRight->toPlainText();

    childForm = new PatchOutputWindow(this);

    //parent window can be in front of child window
    //childForm = new PatchOutputWindow();

    QString strPatch = dmp.patch_toText(dmp.patch_make(str1, str2));
    QTextStream out(&strPatch);

    childForm->setOutputWindowText(strPatch);

    childForm->show();
    @

    [edit: added missing coding tags @ SGaist]


  • Lifetime Qt Champion

    That's it

    On a side note, why the QTextStream ?

    Unless you plan to have multiple PatchOutputWindow shown at the same time, you have a design problem here. Each time you will call the second part of your code, you will replace childForm with a new widget.



  • the sample code used QTextStream is why. What do you suggest.

    I'm aware of the duplicate childforms, not a big concern, but a user may desire to run multiple patches before saving them.


  • Lifetime Qt Champion

    Just that the out variable is never used so there's not need to have it there.

    Then you should write your code taking that possibility into account


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.