2011-02-07 23 views
11

Estoy haciendo un pequeño programa de chat de mensajería, que necesita una lista de canales de chat al usuario se ha unido. Para representar gráficamente esta lista, hice una lista de QPushButtons, que representan un canal diferente. Estos botones se hacen con el método siguiente, y ahí es donde mi problema entra en acción: (. ActivePanelContents es una QWidget que mantiene la lista)¿Cómo pasar variables a los métodos de ranura en 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))); 
} 

El punto es que cada botón debe llamar al método switchTab(string& tabname) cuando se hace clic, incluido el nombre del canal específico como variable. Sin embargo, esta implementación no funciona, y no he podido averiguar cómo hacer esto correctamente.

Respuesta

0

Usted podría intentar tener su ranura switchTab toma ningún argumento y utilizar QObject::sender para obtener el objeto que envía la señal.

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

estar al tanto de las advertencias antes de utilizar el QObject :: emisor en su código –

+0

No estoy seguro de por qué su publicación fue minimizada, pero gracias de todos modos. Has ayudado mucho – parsecer

1

No utilice el método del remitente a menos que sea absolutamente necesario. Vincula la función directamente a ser utilizada solo como una ranura (no se puede llamar directamente). Conserva el comportamiento de hacer que la función acepte una cadena y simplemente crea un mecanismo mediante el cual puedas invocarla.

Un método, entre otros que puede encontrar, es aprovechar el uso de QSignalMapper. Mapeará objetos a valores y regenerará señales de la firma apropiada.

1

lo haría con los objetos "relay":

Crear TabSwitchRelay que es una subclase de QObject con este constructor:

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

También tiene una ranura clicked():

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

Ahora reemplace la línea en su código que se conecta con esto:

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

No se ha probado pero se obtiene la idea básica.

7

Para cadenas y números enteros, puede usar QSignalMapper. En su clase de Messenger, deberá añadir un objeto QSignalMapper mapper, y su función sería el resultado:

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())); 
} 

y después de haber agregado todos los canales a los paneles activos, se llama a

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

Parece que esto no funciona ... simplemente, nunca se llama a switchTab(), aunque no se dan errores en ningún lugar. – Neko

+0

¿'switchTab()' toma 'const QString &'? Si no es así, debes cambiarlo para que así sea. Qt no le permite pasar 'std :: string' (o, en general, cualquier tipo no registrado con' qRegisterMetaType') a través de señales y ranuras. Los errores tipográficos dentro de 'SIGNAL' y' SLOT' no se detectan hasta el tiempo de ejecución, porque esas macros convierten sus argumentos en cadenas. Lo más probable es que Qt esté imprimiendo un mensaje de error en la consola cuando intenta establecer la conexión con 'switchTab (const QString &)'. –

3

Uso QSignalMapper a pasar variables;

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


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

in 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 

} 

espero que mi ans pueden ayudarle a

+0

Gracias por esta respuesta. Estaba usando QSignalMapper con QTNetworkRequest y no sabía que tenía que usar Mapper-> mapeo (datos) para obtener el objeto en tal caso. Simplemente estaba usando qobject_cast (emisor) que solo funciona cuando no tienes parámetro. – fayyazkl

0

si está usando QT5, puede hacerlo a través de lambda:

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

void myMethod(int value) 
{ 
    // do stuff 
} 
Cuestiones relacionadas