Qt信号和插槽传递数据

时间:2016-02-01 07:36:43

标签: c++ qt signals

我对c++ and qt很新。我不确定我是否使用正确的术语来描述我想要实现的目标。但是它就在这里。

我的应用spawns and removes widgets in a gridlayout当用户pushes buttons时。管理成功完成此操作。但是,当用户使用衍生的小部件时,我想要widgets to interact with each other

QList<QLineEdit*> m_ptrLEPathList;
QList<QPushButton*> m_ptrPBList;

qint8 m_noFields;

void MainWindow::on_pbIncFields_clicked()
{
    //create widgets and place on a new row in a gridLayout
    QLineEdit *lineEditPath = new QLineEdit(this);
    QPushButton *pushButton = new QPushButton(this);

    //storing pointers in lists to be able to delete them later.
    m_ptrLEPathList.append(lineEditPath);
    m_ptrPBList.append(pushButton);

    ui->gridLayout->addWidget(m_ptrLEPathList.last(),m_noFields,0);
    ui->gridLayout->addWidget(m_ptrPBList.last(),m_noFields,1);

    connect(m_ptrPBList.last(), SIGNAL(clicked(bool), this, SLOT(on_addPath()));
    m_noFields++;
}

void MainWindow::on_pbDecFields()
{
    //delete last spawned widgets
}

void MainWindow::on_addPath()
{
    QFileDialog getPath();
    getPath.exec();

    //somehow set the text of the line edit spawned on the same row as the pushbutton

}

所以当我按下任何衍生按钮时我的插槽被执行但我不知道如何store the data from the file dialog in the related lineEdit

我尝试做的事情的基本概念是否存在,或者是否有任何其他解决方案可以实现我正在寻找的功能?

5 个答案:

答案 0 :(得分:2)

on_addPath广告位中,您可以使用QObject::sender方法获取点击的按钮,并且假设m_ptrLEPathListm_ptrPBList列表相同,您可以轻松获得相应的{ {1}}:

QLineEdit

答案 1 :(得分:0)

将地图添加到私人部分

QMap<QPushButton*, QLineEdit*> map;

然后

QLineEdit *lineEditPath = new QLineEdit(this);
QPushButton *pushButton = new QPushButton(this);
map.insert(pushButton, lineEditPath);

您可以使用sender()方法,如下所示:

    void on_addPath()
    {
        QFileDialog getPath();
        getPath.exec();

        QObject* obj = sender();
        QPushButton *pb = 0;
        if((pb = qobject_cast<QPushButton *>(obj)) != 0) {
            QLineEdit* lineEdit = map->value(pb, 0);
            if( lineEdit != 0 )
                lineEdit->setText( getPath.<some function to get selected file name> );
        }         

    }

答案 2 :(得分:0)

您在'MainWindow'类的范围之外包含'on_addPath'函数,因此在调用插槽时您无法访问类中的成员元素。

尝试将slot函数包含在类中,并检查您是否可以直接访问成员元素。此外,'lineEditPath'元素必须是成员对象,因此必须将其包含在类定义中。

这样的事情:

void MainWindow::on_addPath()
{
    QFileDialog getPath();
    getPath.exec();

    QStringList fileNames = dialog.selectedFiles();
    if (fileNames.isEmpty())
    {
        return;
    }

    m_lineEditPath->setText(fileNames.first());
}

答案 3 :(得分:0)

首先,void on_addPath()必须为void MainWindow::on_addPath()

至于链接QFileDialog的数据,这很简单。试试这个:

void MainWindow::on_addPath() {
    /* Get the push button you clicked */
    QPushButon *btn = qobject_cast<QPushButton*>( sender() );

    /* Make sure both the lists have the same size */
    Q_ASSERT(m_ptrPBList.size() == m_ptrLEPathList.size());

    /* If the sender is a button in your list */
    if ( m_ptrPBList.contains( btn ) ) {
        /* Get the index of your push button */
        int idx = m_ptrPBList.indexOf( btn );

        /* Get the corresponding line edit */
        QLineEdit *le = m_ptrLEPathList.at( idx );

        /* Get your path */
        QString path = QFileDialog::getOpenFileName( this, "Caption", "Default Location" );

        /* If you path is not empty, store it */
        if ( not path.isEmpty() )
            le->setText( path );
    }
}

答案 4 :(得分:0)

我认为最干净的解决方案是在自定义窗口小部件类中包含QLineEditQPushButton,如果它适合您的项目。这样您就可以使用此类中的文件对话框,而您不必将小部件存储在列表中。很难向您提供所有信息,因为您并没有真正提供您的应用程序应该做的任何细节。但无论如何,自定义窗口小部件类看起来像这样(你应该定义.cpp文件中的所有函数):

#ifndef WIDGETCONTAINER_H
#define WIDGETCONTAINER_H

#include <QWidget>
#include <QLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QFileDialog>

class WidgetContainer : public QWidget
{
    Q_OBJECT
    public:
    WidgetContainer(QWidget *parent = 0) : QWidget(parent)
   {
       setLayout(new QHBoxLayout);
       button.setText("BUTTON");
       layout()->addWidget(&lineEdit);
       layout()->addWidget(&button);

       connect(&button, SIGNAL(clicked()), this, SLOT(buttonPressed()));
   }

private:
    QLineEdit lineEdit;
    QPushButton button;

private slots:
    void buttonPressed()
    {
        QString filename = QFileDialog::getSaveFileName();
        lineEdit.setText(filename);
    }    

};

#endif // WIDGETCONTAINER_H