При работе с Qt встала задача: как правильно организовать доступ к данным родительской формы из дочерней формы. Был выбран вариант передачи указателя на экземпляр данной формы в конструктор дочерней формы. В этом случае у Вас может возникнуть следующая проблема. Для родительской формы вы подключаете заголовочный файл определения класса дочерней формы. Но и дочернему классу нужно сообщить о классе (типе) родительской формы. Если подключить заголовочный файл определения класса родительской формы, то возникнет ситуация циклического подключения этих заголовочных файлов. Чтобы этого избежать, необходимо воспользоваться техникой "опережающего определения" (forward declaration):
bar.h
#include "foo.h"
class bar {
public:
bar();
};
bar.cpp
bar::bar() {
foo f ();
// work with object f
}
foo.h
class bar; // forward declaration
class foo {
public:
foo(bar* obj); // pointer or a reference
};
foo.cpp
#include "bar.h"
#include "foo.h"
foo::foo(bar* obj) {
// work with pointer obj
}
Ниже приведен пример данного подхода, в котором дочерняя форма при отрисовке таблицы со списком элементов обращается к соответствующему списку родительской формы.
item.h
#ifndef ITEM
#define ITEM
#include <QString>
class Item {
private:
int id;
QString description;
public:
Item(int id, QString description) : id(id), description(description) {}
void setId(int id) {
this->id = id;
}
int getId() const {
return id;
}
void setDescription(QString description) {
this->description = description;
}
QString getDescription() const {
return description;
}
};
#endif
mainwindow.h
#ifndef MAINWINDOW
#define MAINWINDOW
#include <QMainWindow>
#include "itemswindow.h"
#include "item.h"
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget* wgt = 0);
QList<Item> itemList;
public slots:
void slotItems();
};
#endif
mainwindow.cpp
#include <QtWidgets>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget* wgt) : QMainWindow(wgt) {
QMenu* menu = new QMenu("Menu");
menu->addAction("Exit", qApp, SLOT(quit()));
menuBar()->addMenu(menu);
// central widget
QWidget* centralWidget = new QWidget;
QVBoxLayout* buttonsWidgetLayout = new QVBoxLayout(centralWidget);
buttonsWidgetLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
QPushButton* itemsBttn = new QPushButton("Items");
itemsBttn->setFixedWidth(150);
buttonsWidgetLayout->addWidget(itemsBttn);
connect(itemsBttn, SIGNAL(clicked()), SLOT(slotItems()));
setCentralWidget(centralWidget);
setWindowTitle("MainWindow");
// for testing
itemList.append(Item(1, "First item"));
itemList.append(Item(2, "Second item"));
itemList.append(Item(3, "Third item"));
itemList.append(Item(4, "Fourth item"));
itemList.append(Item(5, "Fifth item"));
}
void MainWindow::slotItems() {
ItemsWindow* itemsWindow = new ItemsWindow(this, this);
itemsWindow->exec();
delete itemsWindow;
}
itemswindow.h
#ifndef ITEMSWINDOW
#define ITEMSWINDOW
#include <QtWidgets>
#include <item.h>
class MainWindow;
class ItemsWindow : public QDialog {
Q_OBJECT
private:
QTableWidget* table;
public:
ItemsWindow(MainWindow* mw = 0, QWidget* wgt = 0);
};
#endif
itemswindow.cpp
#include "mainwindow.h"
#include "itemswindow.h"
ItemsWindow::ItemsWindow(MainWindow* mw, QWidget* wgt) :
QDialog(wgt, Qt::WindowTitleHint | Qt::WindowCloseButtonHint) {
QVBoxLayout* verticalLayout = new QVBoxLayout;
QHBoxLayout* horizontalBottomLayout = new QHBoxLayout;
QPushButton* okBttn = new QPushButton("&OK");
okBttn->setFixedWidth(60);
connect(okBttn, SIGNAL(clicked()), SLOT(accept()));
horizontalBottomLayout->setAlignment(Qt::AlignRight);
horizontalBottomLayout->addWidget(okBttn);
table = new QTableWidget();
table->setColumnCount(2);
QStringList list;
list << "Id" << "Description";
table->setHorizontalHeaderLabels(list);
table->setEditTriggers(QAbstractItemView::NoEditTriggers);
if (mw != NULL && !mw->itemList.empty()) {
int itemsCnt = mw->itemList.count();
table->setRowCount(itemsCnt);
QTableWidgetItem* tableItem = 0;
for (int i = 0; i < itemsCnt; i++) {
Item item = mw->itemList.at(i);
tableItem = new QTableWidgetItem(QString::number(item.getId()));
tableItem->setTextAlignment(Qt::AlignCenter);
table->setItem(i, 0, tableItem);
tableItem = new QTableWidgetItem(item.getDescription());
table->setItem(i, 1, tableItem);
}
}
this->setWindowTitle("Items");
verticalLayout->addWidget(table);
verticalLayout->addLayout(horizontalBottomLayout);
setLayout(verticalLayout);
}
main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char** argv) {
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
Исходники доступны по данной ссылке - source.