繁体   English   中英

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

[英]How to access to widget class from another dialog class

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

在此输入图像描述

现在我在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;
}

设置

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
}

当然,您应该将mySignaladdItem类连接到Widget类中的mySlot

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

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


编辑

详细说明:

你有Dialog类和mainwindow:

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();
}

结果:

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

在此输入图像描述

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

在此输入图像描述

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

我通常处理这些事情的方式非常简单,但它使单元测试更容易。 我有类似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保持同步,即,如果您添加记录或从模型中删除记录,则更新表格小部件。

免责声明:我实际上并没有尝试编译任何此代码,将其视为pesudo代码;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM