2017-05-20 12 views
0

클래스 MainWindow에 고유 한 헤더와 다른 멤버가있는 여러 QWidgetTable이 포함되어 있습니다. 지금은 매우 간단하기 때문에 클래스 MainWindow 내에 맞춤 테이블 클래스를 정의하고 싶습니다. 예 아래를 참조하십시오 : 내가 추가하고 workflow_table에 대한 행을 제거하는 QPushButtons이Qt : QObject 클래스 내에서 정의 된 클래스의 슬롯을 연결하십시오.

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 
public: 
    explicit MainWindow(SSHClient &client, QWidget *parent = 0); 

public slots: 
    struct Workflow_Table { 
     QTableWidget* widget; 
     QStandardItemModel model; 
     QStringList headers; 

     void addRow(){} 
     void removeRow(){} 
    } workflow_table; 


private: 
    SSHClient& client; 
    Ui::MainWindow* ui; 

    CTL ctl; 
}; 

Ui::MainWindow 내. 이 QPushButton::clicked 신호를 MainWindow::Workflow_Table::addRow에 연결하고 싶습니다. 그러나 어떤 성공도하지 못했고, 제가 시도하고있는 것이 가능한지도 알지 못합니다.

MainWindow::MainWindow(SSHClient &client, QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow), 
    client(client) 
{ 
    ui->setupUi(this); 

    //class CTL is a not a QObject class, yet std::bind causes it to act like a slot here. This statement compiles and runs fine. 
    connect(ui->button_load_ctl, &QPushButton::clicked, this, std::bind(&CTL::saveas, &ctl, "saved.ctl")); 

    //Error: 3 Arguments provided - 4 Expected. I'm almost certain this won't work. 
    connect(ui->button_add, &QPushButton::clicked, this, &MainWindow::Workflow_Table::addRow); 

    //Error: Not a signal or slot declaration. Not sure why this isn't working. 
    connect(ui->button_add, &QPushButton::clicked, this, std::bind(&MainWindow::Workflow_Table::addRow, &workflow_table)); 

    //This doesn't work either. Error 1. 
    connect(ui->button_add, &QPushButton::clicked, this, std::bind(&Workflow_Table::addRow, &workflow_table)); 

} 

은 내가 MainWindow를 QPushButton::clicked로부터 신호 (Workflow_Table QObject를하지 않고) MainWindow::Workflow_Table::addRow 연결할 수 가능한가?

Workflow_Table을 QObject로 만드는 것이 쉬운 해결책이지만, QObject의 범위에서 정의 되었기 때문에 Workflow_Table의 기능을 연결할 수 있는지 궁금합니다. 다른 슬롯 기능을 std :: bind를 사용하여 CTL::saveas 함수처럼 연결할 수 있었으므로 여기에서 비슷한 것을 할 수 있다고 생각합니다. 나는 또한 및 public slots 액세스 지정자 아래로 Workflow_Table을 이동하려고 시도했지만 어느 것도 작동하지 않았습니다.

+1

가장 쉬운 방법은 배치하는 것입니다'addRow()'안에'onPushButton_clicked()'. 메타 오브젝트 시스템을 사용하는 것은 단지 클릭하고 행을 추가하는 것에 대한 지나친 과잉이다. – codekaizer

답변

-1

모두 작동합니다. 실패한 실제 사례를 보여주지 않으면 잘못입니다. 빈 프로젝트에 붙여 넣을 때 모든 것은 두 번째 connect을 제외하고 컴파일됩니다. std::bind 또는 람다를 사용하면 addRow()과 함께 사용할 수 있습니다.

일반적으로 람다가 더 짧 으면 bind을 사용하는 것이 무의미하므로 코드의 선명도가 높아지면 람다를 사용하십시오.

이 작동 :

// https://github.com/KubaO/stackoverflown/tree/master/questions/connect-bind-44081724 
#include <QtWidgets> 
#include <functional> 

class Class : public QWidget 
{ 
    Q_OBJECT 
    QPushButton button; 
    struct CTL { 
     void saveas(const QString &); 
    } ctl; 
    struct Workflow_Table { 
     void addRow() {} 
    } workflow_table; 

public: 
    Class() { 
     connect(&button, &QPushButton::clicked, this, std::bind(&CTL::saveas, &ctl, "saved.ctl")); 
     connect(&button, &QPushButton::clicked, this, [this]{ workflow_table.addRow(); }); 
     connect(&button, &QPushButton::clicked, this, std::bind(&Workflow_Table::addRow, &workflow_table)); 

     // better yet 
     connect(&button, &QPushButton::clicked, this, [this]{ ctl.saveas("saved.ctl"); }); 
     connect(&button, &QPushButton::clicked, this, [this]{ workflow_table.addRow(); }); 

     // or simply, if we know that `this` will outlive `button` (they do by design here), 
     // and that both button and this live in the same thread (again, they do by design here) 
     connect(&button, &QPushButton::clicked, [this]{ ctl.saveas("saved.ctl"); }); 
     connect(&button, &QPushButton::clicked, [this]{ workflow_table.addRow(); }); 
    } 
}; 

int main() {} 
#include "main.moc"