Manipulating QT Ui with different source files

2019-06-03 07:04发布

问题:

I searched for some hours now but I'm not able to find a solution.

My setup is as follows:

Widget.h
Widget.cpp
Widget.ui
Function.h
Function.cpp

I wrote a function in my Function.cpp which adds some entries to a QListWidget in my Widget.ui. It's just a trial and error project:

  • I already included widget.h and ui_widget.h so I can access the classes.
  • The Widget is the QWidget template which you can create with the QtDesigner.
  • In there is a QListWidget and a QButton.

If I click the QButton then it calls the function in Function.cpp which will add an item to the QListWidget.

Do i have to write a custom slot for this or is there another way?


EDIT:

As requested, here is the code.

myWidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

namespace Ui {
class myWidget;
}

    class myWidget : public QWidget
{
    Q_OBJECT

public:
    explicit myWidget(QWidget *parent = 0);
    ~myWidget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::myWidget *ui;
};

#endif // MYWIDGET_H

The myWodget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"

myWidget::myWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::myWidget)
{
    ui->setupUi(this);
}

myWidget::~myWidget()
{
    delete ui;
}

void myWidget::on_pushButton_clicked()
{
    ui->listWidget->addItem("Some Item");
}

The myWidget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>myWidget</class>
 <widget class="QWidget" name="myWidget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QListWidget" name="listWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>20</y>
     <width>256</width>
     <height>192</height>
    </rect>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>110</x>
     <y>240</y>
     <width>75</width>
     <height>23</height>
    </rect>
   </property>
   <property name="text">
    <string>add</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

The Functions.h

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

class Functions
{
public:
    Functions();
};

#endif // FUNCTIONS_H

And the Functions .cpp

#include "functions.h"
#include "myWidget.h" //there seems no effect between ui_mywidget.h and this one ...

Functions::Functions()
{
}

Ive tried to add

Ui::myWidget *ModUi = new myWidget;
ModUi->ui->listWidget->addItem("SomeItem");

I tried this with and without Q_OBJECT in the Functions class in different variations. I was very creative in this case ^^

I hope this helps to understand?

回答1:

Try this:

class Functions; // Forward declaration    
class myWidget : public QWidget
{
    Q_OBJECT
public:
    explicit myWidget(QWidget *parent = 0);
    ~myWidget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::myWidget *ui;
    Functions*fun;  // member ptr
    friend class Functions; // allow access to private members
};

And implementation:

[...]
#include "Functions.h"

myWidget::myWidget(QWidget *parent) :
   QWidget(parent),
   ui(new Ui::myWidget),
   fun(new Functions(this))   // initializer list
{
    ui->setupUi(this);
}

myWidget::~myWidget()
{
    delete ui;
    delete fun;  // we new'ed it so we have to delete it!
}

void myWidget::on_pushButton_clicked()
{
    fun->doIt(); // call to the function
}

The Function.h

[...]

class myWidget; // Forward declaration

class Functions
{
public:
    Functions(myWidget *wid);
    void doIt();
private:
    myWidget *widget; // Member pointer to the main widget
};

And the Function.cpp

[...]

#include "ui_mywidget.h"         
#include "myWidget.h"

Functions::Functions(myWidget *wid):widget(wid) // init the ptr
{
}

void Function::doIt()            
{
   widget->ui->listWidget->addItem("SomeItem"); // add the items
}


回答2:

You probably need to include both "myWidget.h" and "ui_mywidget.h" in your functions.cpp file. You need the first to know what myWidget is, in order to access it's ui member variable. You need the second to know what the ui variable contains.

Something along these lines should work, although probably not as you expect:

#include "functions.h"
#include "myWidget.h"
#include "ui_mywidget.h"

Functions::Functions()
{
    // The following line creates a new widget, and does not use any existing
    // widgets (like you probably expect it to).
    myWidget *ModUi = new myWidget;
    ModUi->ui->listWidget->addItem("SomeItem");
}