如何从另一个对话框类访问窗口小部件类

时间:2014-09-30 13:31:23

标签: c++ qt class user-interface qt5

首先,我有两节课。 First类称为Widget,第二类称为addItem Widget类是应用程序ui的main class(main window),但addItem类只是窗口,单击添加人员以添加新联系人时出现。
此外,Widget类还有一个名为tableWidget的子元素。

enter image description here

现在我在addItem课程,如何访问tableWidget课程后的Widget元素?

小工具类(.h)

namespace Ui {
    class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

protected:
    void resizeEvent(QResizeEvent *event);

private slots:
    void on_delete_btn_clicked();   
    void on_add_btn_clicked();

private:
    Ui::Widget *ui;
};

addItem类(.h)

namespace Ui {
    class addItem;
}

class addItem : public QDialog
{
    Q_OBJECT

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

private slots:
    void on_addBtn_clicked();

private:
    Ui::addItem *ui;
};

修改

以下方法属于addItem类。

addItem.cpp:

void addItem::on_addBtn_clicked(){
    emit mySignal(ui->name_txt->text(), ui->address_txt->text(), ui->phoneNum_txt->text(), ui->mobileNum_txt->text());
    Widget *widget = new Widget;
    connect(this, SIGNAL(mySignal(QString,QString,QString,QString)), widget, SLOT(addMyItem(QString,QString,QString,QString)));
    this->close();
}

另请参阅我编写的其余代码:

addItem.h:

signals:
    void mySignal(QString, QString, QString, QString);

Widget.h (主窗口):

private slots:
    void addMyItem(QString, QString, QString, QString);

Widget.cpp (主窗口):

void Widget::addMyItem(QString name, QString address, QString phone_number, QString mobile_number){
    qDebug() << name << "\n" << address << "\n" << phone_number << "\n" << mobile_number;
}

2 个答案:

答案 0 :(得分:8)

设置

public:
    Ui::Widget *ui;

不是好习惯,所以你可以使用getter和setter。

例如,如果您想从QTableWidget获取文字,请提供示例方法

QString Widget::getCellData(int row, int col)
{
    return ui->tableWidget->item(row,col)->text();
}

设置数据:

void Widget::setCellData(int row, int col, QString txt)
{
    //create item if you need
    ui->tableWidget->item(row,col)->setText(txt);
}

等等。我希望你能理解主要思想以及如何去做。

但你也可以使用信号和插槽:

例如用户点击添加按钮,你想在表中添加新数据,然后从addItem按钮信号发出:

 emit mySignal(name, address, phone , mobile);

其中name为ui->nameLineEdit->text(),依此类推。只需从lineEdit中获取文本并发送即可。

使用Widget课程中的特殊插槽抓住它。在此插槽中,您可以创建新行和设置数据。

void Widget::mySlot(QString name,QString address,QString phone ,QString mobile)
{
    //create cells and set data in it
}

当然,您应该将mySignal课程从addItem课程连接到mySlot课程中的Widget

addItem *mDialog = new addItem;
connect(mDialog,SIGNAL(mySignal(QString,QString,QString,QString)),this,SLOT(mySlot(QString,QString,QString,QString)));

结论:我认为,你应该使用信号和插槽。


修改

详细说明:

你有Dialog类和主窗口:

dialog.h:

signals:
    void mySignal(QString,QString,QString,QString);

dialog.cpp当用户点击我们获取数据时,发出信号并关闭对话框。

void Dialog::on_addItemButton_clicked()
{
    emit mySignal(ui->lineEdit_2->text(),ui->lineEdit_3->text(),ui->lineEdit_4->text(),ui->lineEdit_5->text());
    this->close();
}

mainwindow.h

private slots:
      void addMyItems(QString,QString,QString,QString);

mainwindow.cpp

void MainWindow::addMyItems(QString name,QString address,QString phone ,QString mobile)
{
    ui->tableWidget->setRowCount(ui->tableWidget->rowCount() + 1);//increase row count by 1

    int row = ui->tableWidget->rowCount() - 1;

    //set all data in cells
    ui->tableWidget->setItem(row,0,new QTableWidgetItem(name));
    ui->tableWidget->setItem(row,1,new QTableWidgetItem(address));
    ui->tableWidget->setItem(row,2,new QTableWidgetItem(phone));
    ui->tableWidget->setItem(row,3,new QTableWidgetItem(mobile));
}

主窗口中的按钮插槽,打开对话框:

void MainWindow::on_Add_clicked()
{
    Dialog *dia = new Dialog;//our dialog
    dia->setAttribute(Qt::WA_DeleteOnClose);//we don't want memory leak
    //connection
    connect(dia,SIGNAL(mySignal(QString,QString,QString,QString)),this,SLOT(addMyItems(QString,QString,QString,QString)));
    dia->setModal(true);//you can use modal window instead of exe()
    dia->show();
}

结果:

我点击了添加按钮并进入对话框:

enter image description here

现在我设置一些数据并点击Additem按钮:

enter image description here

如您所见,我们的连接正常,数据正确放置在tableWidget中。

答案 1 :(得分:0)

我通常处理这些事情的方式非常不合适,但它使单元测试变得更容易。我有类似MVC(模型 - 视图 - 控制器)的东西,但在Qt中,V和C是一个。

例如,模型可以是:

class Record
{
public:
  std::string mName;
  std::string mAddress;
  std::string mPhoneNumber;
  std::string mMobileNumber;
};

class Model
{
public:
  void AddRecord(std::unique_ptr<Record> rec)
  {
      mRecords.emplace_back(std::move(rec));
  }

  const Record* ItemAt(size_t index) const
  {
     if (index > mRecords.size()) { return nullptr; }
     return mRecords(index);
  }

  size_t NumRecords() const
  {
    return mRecords.size();
  }
private:
  std::vector<std::unique_ptr<Record> mRecords;
};

然后在您的main函数中,您可以构建一个模型并将其传递到主/视图窗口:

int main( int argc, char **argv )
{
    // Create app instance
    QApplication a( argc, argv );

    Model model;
    MainWindow mainWindow(model); // MainWindow stores a reference to the model
    mainWindow.exec();

创建子对话框时,只需传递模型。或者让它返回std::unique_ptr<Record>

void MainWindow::on_Add_clicked()
{
    Dialog *dia = new Dialog(this, mModel);//Where mModel is the Model instance reference we passed to Widget in main()
    dia->exec();
}

值得注意的是,Qt为视图提供了自己的模型类。您可以使用自己的Model类,并在视图模型更改时让Qts视图模型自动更新UI。但这要先进得多。现在,您可以手动使模型与UI保持同步,即如果您添加记录或从模型中删除记录,则更新表格小部件。

免责声明:我并没有真正尝试编译任何此代码,将其视为伪造代码;)