首先,我有两节课。
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;
}
答案 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();
}
结果:
我点击了添加按钮并进入对话框:
现在我设置一些数据并点击Additem按钮:
如您所见,我们的连接正常,数据正确放置在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保持同步,即如果您添加记录或从模型中删除记录,则更新表格小部件。
免责声明:我并没有真正尝试编译任何此代码,将其视为伪造代码;)