2011-02-07 12 views
11

Sto facendo un piccolo programma di messaggistica chat, che richiede un elenco di canali di chat che l'utente ha aggiunto. Per rappresentare graficamente questo elenco, ho creato un elenco di QPushButtons, che rappresentano tutti un altro canale. Questi pulsanti sono realizzati con il seguente metodo, ed è lì che il mio problema entra in gioco: (. ActivePanelContents è un QWidget che contiene l'elenco)Come passare le variabili ai metodi di slot in QT?

void Messenger::addToActivePanels(std::string& channel) 
{ 
    activePanelsContents = this->findChild<QWidget *>(QString("activePanelsContents")); 
    pushButton = new QPushButton(activePanelsContents); 
    pushButton->setObjectName("pushButton"); 
    pushButton->setGeometry(QRect(0, 0, 60, 60)); 
    pushButton->setText(""); 
    pushButton->setToolTip(QString(channel.c_str())); 
    pushButton->setCheckable(true); 
    pushButton->setChecked(false); 
    connect(pushButton, SIGNAL(clicked()), this, SLOT(switchTab(channel))); 
} 

Il punto è che ogni pulsante deve chiamare il metodo switchTab(string& tabname) quando si fa clic, includendo il nome del canale specifico come variabile. Questa implementazione però non funziona e non sono stato in grado di scoprire come farlo correttamente.

risposta

0

Si potrebbe provare ad avere lo slot switchTab senza argomenti e utilizzare QObject::sender per ottenere l'oggetto che ha inviato il segnale.

Messenger::switchTab() 
{ 
    QObject* sender = this->sender(); 
    QPushButton* button = qobject_cast<QPushButton*>(sender); 
    if(button) 
    { 
    // Do stuff... 
    } 
} 
+0

essere a conoscenza delle avvertenze prima di utilizzare il QObject :: mittente nel tuo codice –

+0

Non sei sicuro del motivo per cui il tuo post è stato minimizzato, ma grazie comunque. Hai aiutato molto – parsecer

1

Non utilizzare il metodo del mittente a meno che non sia assolutamente necessario. Lega direttamente la funzione ad essere utilizzata solo come uno slot (non può essere chiamato direttamente). Mantenere il comportamento di avere la funzione accetta una stringa e semplicemente creare un meccanismo con il quale è possibile chiamarlo.

Un metodo, tra gli altri che si potrebbe trovare, è quello di utilizzare QSignalMapper. Mapperà gli oggetti ai valori e rigenererà i segnali della firma appropriata.

1

voglio farlo con oggetti "relay":

Create TabSwitchRelay che è una sottoclasse di QObject con questo costruttore:

TabSwitchRelay::TabSwitchRelay(QObject *parent, Messanger * m, const QString & c) 
: QObject(parent), m_messanger(m), m_channel(c) 
{ 
} 

Essa ha anche uno slot clicked():

void TabSwitchRelay::clicked() 
{ 
    m_messager->switchTab(m_channel); 
} 

Ora sostituire la linea nel codice che si connette con questo:

TabSwitchRelay * tabRelay = new TabSwitchRelay(pushButton, this, channel); 
connect(pushButton, SIGNAL(clicked()), tabRelay, SLOT(clicked())); 

Non è testato ma si ottiene l'idea di base.

7

Per stringhe e numeri interi, è possibile utilizzare QSignalMapper. Nella classe Messenger, si dovrebbe aggiungere un oggetto QSignalMapper mapper, e la funzione sarà simile:

void Messenger::addToActivePanels(std::string& channel) 
{ 
    activePanelsContents = this->findChild<QWidget *>(QString("activePanelsContents")); 
    pushButton = new QPushButton(activePanelsContents); 
    // ... 
    connect(pushButton, SIGNAL(clicked()), &mapper, SLOT(map())); 
    mapper.setMapping(pushButton, QString(channel.c_str())); 
} 

e dopo aver aggiunto tutti i canali ai pannelli attivi, si chiama

connect(&mapper, SIGNAL(mapped(const QString &)), this, SLOT(switchTab(const QString &))); 
+0

Questo non sembra funzionare ... switchTab() semplicemente non viene mai chiamato, anche se non ci sono errori da nessuna parte. – Neko

+0

Does 'switchTab()' prenda un 'const QString &'? In caso contrario, è necessario modificarlo in modo che lo faccia. Qt non ti permette di passare 'std :: string' (o, in generale, qualsiasi tipo non registrato con' qRegisterMetaType') attraverso segnali e slot. I refusi all'interno di 'SIGNAL' e' SLOT' non vengono rilevati fino al runtime, perché quelle macro trasformano i loro argomenti in stringhe. È probabile che Qt stia stampando un messaggio di errore sulla console quando tenta di effettuare la connessione a 'switchTab (const QString &)'. –

3

Usa QSignalMapper a passare le variabili;

 QSignalMapper* signalMapper = new QSignalMapper (this) ; 
     QPushButton *button = new QPushButton(); 


     signalMapper -> setMapping (button, <data>) ; 
     connect (signalMapper, SIGNAL(mapped(QString)), this, 
        SLOT(buttonClicked(QString))) ; 

nello slot i.e

void class::buttonClicked(QString data){ 

    //use data 
    // to get sender 
    QSignalMapper *temp = (QSignalMapper *)this->sender(); 
    QPushButton *btn = (QPushButton *)temp->mapping(data); 
    // use btn 

} 

auguro che il mio ans possono aiutare a

+0

Grazie per questa risposta. Stavo usando QSignalMapper con QTNetworkRequest e non sapevo che dovevo usare Mapper-> mapping (dati) per ottenere l'oggetto in questo caso. Stavo semplicemente usando qobject_cast (mittente) che funziona solo quando non hai parametri. – fayyazkl

0

se si sta utilizzando QT5, puoi farlo attraverso lambda:

connect(sender, &Sender::valueChanged, [=](){ myMethod(5); }); 

void myMethod(int value) 
{ 
    // do stuff 
} 
Problemi correlati