2017-01-19 51 views
0

我有一個叫做密碼的基類,有很多子類像異或,凱撒的,仿射等Qt的:在點擊實例化對象可通過按鈕

我有按鈕和目錄操作搜索按鈕列表來實例化一個不同的對象點擊按鈕

爲Button1當我想要實例child1 爲BUTTON2我想要實例的child2 等

std::vector<std::string> ciphers = {"Xor", "Caesar", "Affine", "AveMaria", "Autoclave", "Vigenere"}; 

for (std::vector<std::string>::iterator it = ciphers.begin(); it != ciphers.end(); it++) 
    associative_buttons.push_back(std::make_pair(*it, new QPushButton (QString::fromStdString(*it), this))); 

int y = 15; 
QFont font ("Courier"); 
for (std::list<std::pair<std::string, QPushButton*> >::iterator it = associative_buttons.begin(); it != associative_buttons.end(); it++) 
{ 
    (std::get<1>(*it))->setFont(font); 
    (std::get<1>(*it))->setGeometry(40, 30, 160, 50); 
    (std::get<1>(*it))->move(15, y); 
    y += 50; 

    QObject::connect(std::get<1>(*it), SIGNAL(clicked()), this, SLOT()); // my problem is here 
} 

這可能嗎? 我有一個對象工廠情況下,如果它可以幫助

編輯:

我得到一個錯誤:win.cpp:73:ERREUR:不能調用成員函數 '的QObject *的QObject ::發件人()const的'沒有對象 if(std :: get < 1>(* it)== QApplication :: sender())

這是正常嗎? 我的QApplication未聲明有 ^

#include "win.h" 

Win::Win() : QWidget() 
{ 
    c = nullptr; 

    std::vector<std::string> ciphers = {"Xor", "Caesar", "Affine", "AveMaria", "Autoclave", "Vigenere"}; 

    for (std::vector<std::string>::iterator it = ciphers.begin(); it != ciphers.end(); it++) 
     associative_buttons.push_back(std::make_pair(*it, new QPushButton (QString::fromStdString(*it), this))); 

    int y = 15; 
    QFont font ("Courier"); 
    for (std::list<std::pair<std::string, QPushButton*> >::iterator it = associative_buttons.begin(); it != associative_buttons.end(); it++) 
    { 
     (std::get<1>(*it))->setFont(font); 
     (std::get<1>(*it))->setGeometry(40, 30, 160, 50); 
     (std::get<1>(*it))->move(15, y); 
     y += 50; 

     QObject::connect(std::get<1>(*it), SIGNAL(clicked()), qApp, SLOT(handleButtons())); 
    } 
} 

Win::~Win() 
{ 
    for (std::list<std::pair<std::string, QPushButton*> >::iterator it = associative_buttons.begin(); it != associative_buttons.end(); it++) 
     it = associative_buttons.erase(it); 
} 

constexpr unsigned int str2int(const char* str, int h = 0) 
{ 
    return !str[h] ? 5381 : (str2int(str, h + 1) * 33)^str[h]; 
} 

void Win::CreateInstance(std::string name) 
{ 
    Cipher * instance = nullptr; 

    switch (str2int(name.c_str())) 
    { 
    case str2int("Xor") : 
     instance = new Xor(); 
     break; 
    case str2int("Caesar") : 
     instance = new Caesar(); 
     break; 
    case str2int("Vigenere") : 
     instance = new Vigenere(); 
     break; 
    case str2int("Affine") : 
     instance = new Affine(); 
     break; 
    case str2int("AveMaria") : 
     instance = new AveMaria(); 
     break; 
    case str2int("Autoclave") : 
     instance = new Autoclave(); 
     break; 
    default: 
     break; 
    } 

    c = instance; 
} 

void Win::handleButtons() 
{ 
    for (std::list<std::pair<std::string, QPushButton*> >::iterator it = associative_buttons.begin(); it != associative_buttons.end(); it++) 
    { 
     if (std::get<1>(*it) == QApplication::sender()) // error is here 
      CreateInstance(std::get<0>(*it)); 
    } 

    if (c != nullptr) 
     c->run(); 
} 

@ ab.o2c

編輯:

我使用的QObject,而不是QApplication的 這裏是代碼,如果有人需要它finnaly固定它

#include "win.h" 

Win::Win() : QWidget() 
{ 
    c = nullptr; 

    std::vector<std::string> ciphers = {"Xor", "Caesar", "Affine", "AveMaria", "Autoclave", "Vigenere"}; 

    for (std::vector<std::string>::iterator it = ciphers.begin(); it != ciphers.end(); it++) 
     associative_buttons.push_back(std::make_pair(*it, new QPushButton (QString::fromStdString(*it), this))); 

    int y = 15; 
    QFont font ("Courier"); 
    for (std::list<std::pair<std::string, QPushButton*> >::iterator it = associative_buttons.begin(); it != associative_buttons.end(); it++) 
    { 
     (std::get<1>(*it))->setFont(font); 
     (std::get<1>(*it))->setGeometry(40, 30, 160, 50); 
     (std::get<1>(*it))->move(15, y); 
     y += 50; 

     QObject::connect(std::get<1>(*it), SIGNAL(clicked()), this, SLOT(handleButtons())); 
    } 
} 

Win::~Win() 
{ 
    for (std::list<std::pair<std::string, QPushButton*> >::iterator it = associative_buttons.begin(); it != associative_buttons.end(); it++) 
     it = associative_buttons.erase(it); 
} 

constexpr unsigned int str2int(const char* str, int h = 0) 
{ 
    return !str[h] ? 5381 : (str2int(str, h + 1) * 33)^str[h]; 
} 

void Win::CreateInstance(std::string name) 
{ 
    Cipher * instance = nullptr; 

    switch (str2int(name.c_str())) 
    { 
    case str2int("Xor") : 
     instance = new Xor(); 
     break; 
    case str2int("Caesar") : 
     instance = new Caesar(); 
     break; 
    case str2int("Vigenere") : 
     instance = new Vigenere(); 
     break; 
    case str2int("Affine") : 
     instance = new Affine(); 
     break; 
    case str2int("AveMaria") : 
     instance = new AveMaria(); 
     break; 
    case str2int("Autoclave") : 
     instance = new Autoclave(); 
     break; 
    default: 
     break; 
    } 

    c = instance; 
} 

void Win::handleButtons() 
{ 
    for (std::list<std::pair<std::string, QPushButton*> >::iterator it = associative_buttons.begin(); it != associative_buttons.end(); it++) 
    { 
     if (std::get<1>(*it) == QObject::sender()) 
      CreateInstance(std::get<0>(*it)); 
    } 

    if (c != nullptr) 
     c->run(); 
} 
+0

是否有一個原因,你不想爲每個按鈕設置一個單獨的插槽? –

+0

是的,實際上是 每個按鈕都有一個內容字符串,顯示在按鈕上 而我想爲每個按鈕實例化一個不同的對象 – RomMer

+0

這就是不同按鈕的原因?但爲什麼不使slotButton1,slotButton2,...並連接每個按鈕與相關的插槽 –

回答

0

我想你可以用QSignalMapper來做你想做的事。其目的是映射來自一堆對象的信號並將它們引導到一個插槽,但添加了一個參數來枚舉它們來自哪個對象。我想這正是你想在這裏做的。您只需創建映射器併爲每個按鈕分配每個按鈕和唯一ID。它避免了爲每個按鈕創建一個唯一的插槽的需要。

它只適用於原始信號沒有任何參數的情況,這對於「點擊」信號是正確的,所以它應該適合您。