PDA

View Full Version : Possible signal mapper problem



MarkoSan
24th January 2008, 07:47
Good morning, sehr geheerte Damen und Herren! :D

I have problem I cannot crack. I have three classes, that need to cooperate. Namely, I am writing language change aware app and I coded a class, derived from QPushButton, which represent a "nation flag button". It is subclassed from QPushButton and also it holds a private member:
private:
qint16 m_iLanguageId; // language id number which is id number from database. When creating an object from CFlagButton, this number is set correctly. But I simply cannot send this number via signal mapper i wrote to its parent window, CLanguageSelectorWidget, which holds more of CFlagButtons (for every langauge in database there is appropriate flag button). Here is signal mapper I wrote:
CFlagButton::CFlagButton(QWidget* pParent,
const QString flagPicture,
const QString flagCaption,
bool captionShown,
const QString langTranslator,
const qint16 iLanguageIdentificator)
{
....
m_pFlagButtonSM=new QSignalMapper(this); // creates new signal mapper
Q_CHECK_PTR(m_pFlagButtonSM); // checks creation
// installation of translator
m_pTranslator=new QTranslator(qApp); // creats new translator
Q_CHECK_PTR(m_pTranslator); // checks creation
m_pTranslator->load(langTranslator); // loads translator
connect(this,
SIGNAL(clicked()),
m_pFlagButtonSM,
SLOT(map())); // connects button to signal mapper
m_pFlagButtonSM->setMapping(this, (int)m_iLanguageId); // sets mapping
/*
connect(m_pFlagButtonSM,
SIGNAL(mapped(int)),
this,
SIGNAL(clicked(const int))); // connects signal mapper to button
connect(this, SIGNAL(clicked(const int)),
pParent, SLOT(translate(const int))); // connects emited signal to slot
*/
connect(m_pFlagButtonSM,
SIGNAL(mapped(int)),
pParent,
SLOT(translate(const int))); // connects signal mapper to translator
....
}pParent here is CLanguageSelectorWidget object and its translate() slot is:
void CLanguageSelectorWidget::translate(const int iLanguageIdentificator)
{
qDebug() << "iLanguageIdentificator: " << iLanguageIdentificator;
qApp->installTranslator(m_LangButtonGroup.at(iLanguageId entificator-1)->translator()); // installs translator
accept(); // closes parent window
}m_LangButton group is defined as:
QList<QPointer<CFlagButton> > m_LangButtonGroup; // language button groupI've entered into debugger, set the breakpoints and the cruical member variable m_iLanguageId holds -4096 or -4098 values (it seems it is not initialized properly)
In constructor of CFlagButton the variable is initalized properly - checked with gdb.
Can nice jpn or other nice experts help me?

wysota
24th January 2008, 09:17
What happens if you remove casting to int in line 19 and remove const from line 31?

By the way, what is the point of having the signal mapper inside the button?

MarkoSan
24th January 2008, 09:40
What happens if you remove casting to int in line 19 and remove const from line 31? Same result, the text was not changed. But the parameter DID TRANSFER SUCCESFULLY!!! How did you know that in first try??!!!


By the way, what is the point of having the signal mapper inside the button? Will correct that, for now I just want to make this thing work.

Sorry for mistake. The parameter is correctly passed between CFlagButton and CLanguageSelectorWidget. But, between CLanguageSelectorWidget and COperationWindow, the int has again value -4096. In COperationWIndow there is a private pointer to CLanguageSelectorWidget. Here is the code of final changeEvent:
void COperationWIndow::changeEvent(QEvent* e)
{
qDebug() << "Change event .."; // debug
if(e->type()==QEvent::LanguageChange)
{
// language has changed
qDebug() << "Language has changed";
m_pButtonMerchandizeConfirmer->setText(tr("IZBERI")); // shows loaded translator caption

// sets dynamically allocated button text
QString queryString("SELECT * FROM `eros`.`grupa` WHERE LanguageIdentificationNumber=%1;");
queryString=queryString.arg(languageSelectorWidget ()->selectedLanguage()); // set up query string
qDebug() << "queryString: " << queryString; // debug
QSqlQuery query(queryString); // setups query from query string
qint16 iIndex=0; // loop index

query.setForwardOnly(true); // sets forward seeking only
while(query.next())
{
// sets button text
m_MerchandizeSelectorButtons.at(iIndex)->setText(query.value(iGroupFieldNAME).toString());
iIndex++; // increase index
}
// **** end of setting dynamic buttons text

}
}Method selectedLanguage() returns -4096 instead of chosen langauge. Why??

MarkoSan
24th January 2008, 17:30
So, no one has idea?! :crying:

wysota
24th January 2008, 17:56
It would be easier if we had the relevant code (and cut out parts that are not relevant).

MarkoSan
24th January 2008, 18:05
Ok, here is COperationWindow.h:
class COperationWIndow : public QWidget
//class COperationWIndow : public QDockWidget
{
Q_OBJECT

public:
COperationWIndow(QWidget* pParent);
~COperationWIndow();
void playVerbalDescription(QString sSound);
// method for getting merchandize description
QString getMerchandizeDescription(qint16 iMerchandizeId);

// inline methods for getting pointers of private members
inline QPointer<CLanguageSelectorWidget> languageSelectorWidget() { return m_pLanguageSelectorWidget; };

private:
QPointer<CMerchandizeBrowser> m_pMerchandizeBrowser; // pointer to merchandize browse
QPointer<QVBoxLayout> m_pVLayout; // pointer to vertical layout
QPointer<QHBoxLayout> m_pHLayout; // pointer to horizotnal layout
QPointer<QHBoxLayout> m_pMainLayout; // pointer to main layout
QPointer<QVBoxLayout> m_pCartLayout; // pointer to vertial layout
QPointer<QPushButton> m_pLeftButtonMerchandizeSelector; // pointer to left merhcandize selector
QPointer<QPushButton> m_pButtonMerchandizeConfirmer; // pointer to merchandize confirmer
QPointer<QPushButton> m_pRightButtonMerchandizeSelector; // pointer to right merhcandize selector
QPalette m_cPalette; // palette for changing colors
QFont m_cFont; // font variable for changing fonts
qint16 m_iSelected; // selected merchandize
QPointer<QTimer> m_pAdvertisementTimer; // timer for advertisement mode
QStringList m_MerchandizeGroupsNames; // structure to store merchandize group names
QPointer<QHBoxLayout> m_pMerchandizeSelectorButtonsLayout; // horiz. layout for merchandize selector buttons
QList <QPushButton*> m_MerchandizeSelectorButtons; // merchandize selector buttons
//QList <QPointer<QPushButton> > m_pMerchandizeSelectorButtons; // merchandize selector buttons
QPointer <QSignalMapper> m_pMerchandizeSelectorButtonSignalMapper; // pointer to buttons signal mapper
QPointer<QPushButton> m_pSoftwareInformationButton; // button for triggering software info
QPointer<CDatabaseFoundation> m_pDatabaseConnection; // connecion to dabase
QPointer<QTabWidget> m_pMerchandizeTabWidget; // ponter to merchandize shooping cart & information widoget
QPointer<CShoppingCart> m_pShoppingCart; // pointer to shopping cart
QPointer<CLanguageSelectorWidget> m_pLanguageSelectorWidget; // language selector widget
QPointer<QPushButton> m_pLanguageSelectorButton; // language selector button

private slots:
// slot for showing left merchandize
void showLeftMerchandize();
// slot for showing right merchandize
void showRightMerchandize();
// slot for choosing merchandize
void chooseMerchandize();
// slot for avertising
void startAdvertising();
// slot for showing software info
//void showSoftwareInfo();
// slot for showing language selector
void showLanguageSelectorWidget();

/* !
* slot for filtering merchandize pictures
*/
void filterMerchandize(int iMerchandizeGroup);

private:
/* !
* creates tab widget
*/
void createShoppingCartWidget(QTabWidget* pParent);
/* !
* creates Merchandize Information Widget
*/
void createMerchandizeInformationWidget(QTabWidget* pParent);
/*!
* language change event filter
*/
void changeEvent(QEvent* e);


signals:
void clicked(const int &iIndex); // pushbutton slot
};

#endif /*COPERATIONWINDOW_H_*/As you can see, here is defined pointer to CLanguageSelectorWidget:
QPointer<CLanguageSelectorWidget> m_pLanguageSelectorWidget; // language selector widgetand here is CLanguageSelectorWidget header:
#define CLANGUAGESELECTORWIDGET_H_

/*!
* \class CLanguageSelectorWidget
* \author VSistemi Marko Frelih s.p.
* \version 1.0
* \date January 2007
* \brief This Qt based class represents a language selector widget, which constist of number of
* CFlagButton objects.
* \details version 1.00 (revision 84): basic functionality
*/

// qt includes
#include <QDialog>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QList>
#include <QFont>
#include <QPalette>
#include <QApplication>
#include <QButtonGroup>
#include <QSqlQuery>
#include <QString>
#include <QVector>

class QWidget; // forward declaration

// custom includes
#include "CFlagButton.h"
#include "cdatabasefoundation.h"

/*!
* class which contains flag buttons
*/
class CLanguageSelectorWidget : public QDialog
{
Q_OBJECT

public:
CLanguageSelectorWidget(QWidget* pParent);
~CLanguageSelectorWidget();
inline QPointer<QHBoxLayout> langaugeButtonsLayout() { return m_pLanguageButtonsLayout; };
inline QPointer<QVBoxLayout> mainLayout() { return m_pMainLayout; };
//inline QList<CFlagButton> languageButtonsList() { return mLanguageButtonsList; };
inline QPalette widgetPalette() { return m_WidgetPalette; };
/*
inline QPointer<CFlagButton> sloLangButton() { return m_pSloLangButton; };
inline QPointer<CFlagButton> ukLangButton() { return m_pUKLangButton; };
inline QPointer<CFlagButton> deuLangButton() { return m_pDeuLangButton; };
inline QPointer<CFlagButton> itaLangButton() { return m_pItaLangButton; };
*/
inline qint16 numberOfLanguages() { return m_iNumberOfLanguages; };
//inline void setNrOfLanguages(qint16 iNumber) { m_iNumberOfLanguages=iNumber; };
inline void selectLanguage(qint16 iSelectedLanguage) { m_iSelectedLanguage=iSelectedLanguage; };
inline qint16 selectedLanguage() { return m_iSelectedLanguage; };

private:
QPointer<QHBoxLayout> m_pLanguageButtonsLayout; // horizontal layout
QPointer<QVBoxLayout> m_pMainLayout; // main layouts
QPalette m_WidgetPalette; // widget palette
QList<QPointer<CFlagButton> > m_LangButtonGroup; // language button group
QPointer<CDatabaseFoundation> m_pDatabaseConnection; // connecion to dabase
qint16 m_iSelectedLanguage; // index of selected langauge
// TODO: automatic hbox creation at higer number of language buttons
QVector<QPointer<QHBoxLayout> > m_LangaugeButtonsLayout; // list of horizontal layers
qint16 m_iNumberOfLanguages; // number of languages

private:
// method for reading database and filling list with lang buttons
QList<QPointer<CFlagButton> > createLangButtons();

private slots:
void translate(const int iLanguageIdentificator);
};

#endif /*CLANGUAGESELECTORWIDGET_H_*/As we can see, here is a QList of CFlagButtons:
QList<QPointer<CFlagButton> > m_LangButtonGroup; // language button groupHere I create object CLanguageSelectorWidget (in COperationWindow constructor):
m_pLanguageSelectorButton=new QPushButton(QPixmap(":/flags/flagLanguageSelector"),
QString(""),
this); // creates lang. selector button
Q_CHECK_PTR(m_pLanguageSelectorButton); // checks creation
m_cPalette=m_pLanguageSelectorButton->palette(); // reads current palette
m_cPalette.setColor(QPalette::Button, Qt::black); // sets up new palette componenet
m_pLanguageSelectorButton->setPalette(m_cPalette); // sets new pallete
m_pLanguageSelectorButton->setIconSize(QSize(128, 128)); // sets icon size
// sets mask for reshaping button
//m_pLanguageSelectorButton->setMask(QPixmap(":/flags/flagLanguageSelector").createHeuristicMask());
connect(m_pLanguageSelectorButton, SIGNAL(clicked()),
this, SLOT(showLanguageSelectorWidget())); // connects click to slotAnd here is contructor of CLanguageSelectorWidget:
CLanguageSelectorWidget::CLanguageSelectorWidget(Q Widget* pParent) : QDialog(pParent)
{
// opens database connection
m_pDatabaseConnection=CDatabaseFoundation::getInst ance(strdbType, strdbHost, strDatabaseName, strdbUserName, strdbPassword);
Q_CHECK_PTR(m_pDatabaseConnection); // checks creation
// **** end of DATABASE CONNECTION

// sets up horiz layout vector
m_LangaugeButtonsLayout.resize(iNumberOfButtons-1); // resizes layout pointer vector
// **** end of setup horiz layout vector
m_LangButtonGroup=createLangButtons(); // creates language buttons from database
m_pLanguageButtonsLayout=new QHBoxLayout(); // creates new horiz layout
Q_CHECK_PTR(m_pLanguageButtonsLayout); // checks creation
for(int iIndex=0; iIndex<m_LangButtonGroup.size(); iIndex++)
m_pLanguageButtonsLayout->addWidget(m_LangButtonGroup.at(iIndex));
setWindowModality(Qt::WindowModal); // sets modal flag

// sets window palette
setAutoFillBackground(true); // sets background auto fill ON
m_WidgetPalette=this->palette(); // reads current palette
m_WidgetPalette.setColor(QPalette::Background, Qt::black); // sets background color of widget
setPalette(m_WidgetPalette); // installs modified palette

// sets window flags
Qt::WindowFlags flags=Qt::FramelessWindowHint | Qt::Dialog; // sets window flags
setWindowFlags(flags); // sets window flags

m_pMainLayout=new QVBoxLayout(); // creates main layout
Q_CHECK_PTR(m_pMainLayout); // checks creation
m_pMainLayout->addLayout(m_pLanguageButtonsLayout); // adds layout
setLayout(m_pMainLayout); // sets new layout
}Do you need anything else?

wysota
24th January 2008, 22:53
Ok, but I asked for the relevant code, not the whole code :) Could you suggest which part is relevant to the problem?


inline QPointer<QHBoxLayout> langaugeButtonsLayout() { return m_pLanguageButtonsLayout; };
What is this? Why do you return a QPointer to a layout?

Why does translate() take const int and not just int?

QVector and QList of QPointers? Why?

MarkoSan
24th January 2008, 23:33
It is not a whole code, just classes relevenat to problem. Well, as you can see, the problem is when I try to find out which language is selected in COperationWindow object, I get weird values. The signal mapper communication between CFlagButton and CLanguageSelectorWodget works ok, I've checked it with gdb. Why does method
selectedLanguage() from
QPointer<CLanguageSelectorWidget> m_pLanguageSelectorWidget; returns weird results?? This is my question excatly. Other your remarks regarding code will be fixed in future.

wysota
25th January 2008, 01:23
Where do you call selectLanguage()?

m_iSelectedLanguage is not initialized in the constructor and selectLanguage() is the only method that changes its value. If you don't call it, it will contain a random number, possibly the one you are receiving...

And by the way - where is the signal mapper in all that?

MarkoSan
25th January 2008, 02:53
God damn, wysota, thank you very very much, If you ever come to Slovenia (with jpn), contact me, I owe you and a jpn a lot of beers!!!!!!!! IT WORKS NOW!!!!! :D:rolleyes:

wysota
25th January 2008, 10:07
What if I come without jpn? :)

MarkoSan
25th January 2008, 12:31
you're welcome, it is urgent to drink some beers. :crying::confused::rolleyes:

jpn
25th January 2008, 12:55
If you ever come to Slovenia (with jpn), contact me, I owe you and a jpn a lot of beers!!!!!!!!
Thanks for the invitation. ;)


What if I come without jpn? :)
Does that mean you'd rather go without me? :)

MarkoSan
25th January 2008, 14:11
I do not know what relation are you two in, but I invited both. :D I reserve 60 beers per developer per weekend, is this enough?:D