Results 1 to 15 of 15

Thread: QSignalMapper and argument problems

  1. #1
    Join Date
    Aug 2010
    Posts
    62
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default QSignalMapper and argument problems

    Hello!
    I use a QSignalMapper to map the clicked() events of a QPushButton matrix:

    buttonmatrix.h:
    Qt Code:
    1. #ifndef BUTTONMATRIX_H
    2. #define BUTTONMATRIX_H
    3.  
    4. #include <QPushButton>
    5. #include <QObject>
    6. #include <QSignalMapper>
    7.  
    8. class ButtonMatrix : QObject
    9. {
    10. Q_OBJECT
    11. private:
    12. int nrow;
    13. int ncol;
    14. QSignalMapper *signalMapper;
    15. public:
    16. ButtonMatrix(int nrow, int ncol);
    17. ~ButtonMatrix();
    18. void Show(QWidget*);
    19. public slots:
    20. void SetItem(const QString &ID); // this slot is called by the signal clicked() of the button identified by ID
    21. };
    22.  
    23. #endif // BUTTONMATRIX_H
    To copy to clipboard, switch view to plain text mode 


    buttonmatrix.cpp:
    Qt Code:
    1. #include "buttonmatrix.h"
    2. #include <QPushButton>
    3. #include "mainwindow.h"
    4. #include <QSignalMapper>
    5. #include <QString>
    6. #include <QChar>
    7. #include "stdio.h"
    8. #include "mymacros.h"
    9. #include "string.h"
    10.  
    11. ButtonMatrix::ButtonMatrix(int nr, int nc)
    12. {
    13. ncol=nc;
    14. nrow = nr;
    15. p = new QPushButton*[nrow];
    16. for (int i=0; i<nrow; i++)
    17. p[i] = new QPushButton[ncol];
    18. }
    19.  
    20. void ButtonMatrix::Show(QWidget *obj)
    21. {
    22. int alt = (obj->height()-100)/nrow;
    23.  
    24. signalMapper= new QSignalMapper(this);
    25.  
    26. QString ID; // the format of the ID string will be "iijj" where i = index of rows, j = index of columns
    27. char aux1[3], aux2[3], aux3[5]; //used to convert into strings and then append the i&j indexes
    28. for (int i=0; i<nrow; i++)
    29. {
    30. if (i>=10)
    31. sprintf(aux1,"%d", i);
    32. else
    33. sprintf(aux1,"0%d", i); // this ensures that the format of the first part of ID will be "ii"
    34.  
    35. for (int j=0; j<ncol; j++)
    36. {
    37. if (j>=10)
    38. sprintf(aux2,"%d", j);
    39. else
    40. sprintf(aux2,"0%d", j); // this ensures that the format of the second part of ID will be "jj"
    41.  
    42. p[i][j].setParent(obj);
    43. p[i][j].setGeometry(50+(j*alt), 70 +(i*alt),alt, alt);
    44. connect(&p[i][j], SIGNAL(clicked()), signalMapper, SLOT(map())); //connect the clicked() slot of the ij-th button with the map() slot of the signal mapper...
    45. sprintf(aux3, "%s%s", aux1, aux2);
    46. ID = tr(aux3); // (creating the ID string in "iijj" format)
    47. signalMapper->setMapping(&p[i][j], ID); //...and then associate ID to the ij-th button of the matrix
    48. p[i][j].show();
    49. }
    50. }
    51.  
    52. connect(signalMapper, SIGNAL(mapped(const QString &)),
    53. this, SLOT(SetItem(const QString &))); // when a button of the matrix gets clicked the SetItem slot of the ButtonMatrix will be called
    54. }
    55.  
    56. void ButtonMatrix::SetItem(const QString & ID) // HERE I'd like a few more arguments for SetItem to work properly.
    57. {
    58. int i, j;
    59. const QChar *aux = ID.data();
    60. i = aux[0].digitValue()*10 + aux[1].digitValue();
    61. j = aux[2].digitValue()*10 + aux[3].digitValue();
    62.  
    63.  
    64. // here I need an integer and a custom object coming from the main
    65. //but the SLOT cannot gain more parameters than one
    66. }
    67.  
    68. ButtonMatrix::~ButtonMatrix()
    69. {
    70. for (int i=0; i<nrow; i++)
    71. delete [] p[i];
    72. delete p;
    73. }
    To copy to clipboard, switch view to plain text mode 

    in the code I highlited the problem. Simply I need at least two more parameters for the SLOT function that responses the clicked() SIGNALs of the button matrix, but the QSignalMapper doesn't allow me to gain more parameters than one...
    is there another way to connect a button matrix without being obliged to use only one parameter in the SLOT function?

    thanks

  2. #2
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: QSignalMapper and argument problems

    I suggest creating custom signals and slots.

    If you want to have a clicked signal with more parameters, then just create a subclassed widget and send a custom signal when clicked with the extra parameters.

  3. #3
    Join Date
    Aug 2010
    Posts
    62
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSignalMapper and argument problems

    I'm not sure how to get the things done.. this is the map of signal/slot that is implemented (every arrow is a connect() ):

    (SIGNAL) p[i][j].clicked() -> (SLOT) ButtonMatrix.SetItem(const QString & ID) (this is set using signalMapper)
    here is a plan of signal/slot I'd like to implement. p, one of the members of ButtonMatrix, is now a myButton pointer. myButton is a class derived from QPushButton:

    (SIGNAL) p[i][j].clicked() -> (SLOT) p[i][j].CallNext1() ( this SLOT only emittes CallNext2(args) SIGNAL) -> p[i][j].CallNext2(QString &ID, int type, MyObj obj) -> (SLOT) p[i][j].doSomethingOnTheParameters(QString &ID, int type, MyObj obj)
    I'm not convinced for three reasons:
    1) it's too long and ugly, peraphs I can save one pass like CallNext1() SLOT but I should have access to clicked() SIGNAL to send the SIGNAL CallNext2( args );
    2) I have no idea on how to implement the second "arrow". to send CallNext2 (arg) SIGNAL I need the args but I cannot gain them previously (it's a vicious circle)
    3) peraphs I didn't catch all SIGNAL/SLOT functions?

    (yes, I'm a newbie )

    thanks a lot

  4. #4
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QSignalMapper and argument problems

    Why do you need more arguments? Can't you get these information in the slot? With the mapper you can identify which button was clicked and you can get a pointer to that button. And all other information are - I guess so - in private variables. For them you can make getter function.

    May be you say us which informations you need (as arguments) and where they are in your architecture.

  5. #5
    Join Date
    Aug 2010
    Posts
    62
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSignalMapper and argument problems

    I'm writing a program which allows to design the map of a labirith. this will be saved in a file and another program will allow to play this labirith.

    I thought to divide the labirith into squares, each of them can assume 4 status: 0 = empty, 1 = entry, 2 = exit, 3 = wall. In this way I can gain all informations about it (where is the entry, the exit, where are the walls, etc...).

    The user chooses the tool to use (set an entry, set an exit, set a wall, remove something) by using a toolbar with, of course, four buttons.

    To gain the map of the labirith from the user I show a button matrix and every button is a square of the logical map, so every button can be "set" to a status. The status cannot be stored in the buttons (obvious).
    So the problem is that on the click() event of the i-j button the program should:

    1) change the background image of the button so that the user can see where (e.g.) the wall is; (I've done it because all I needed was ID string)
    2) store the status of the matrix in a matrix of integers in which every item can assume 4 status depending on the tool choosen in the toolbar (THIS is the problem)

    Now in che SLOT I need the ID string to identify the button on which I should operate, and at least the tool choosen by the user (an integer variable)! but the SLOT doesn't allow me to introduce the tool parameter...moreover it should be better to distinguish the button matrix from the status matrix (the integer matrix which stores the labirinth status), so I need another argument in the SLOT to set this matrix...

  6. #6
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QSignalMapper and argument problems

    First you can store the information (wall/exit...) in the button if you subclass QPushButton and add that functionality. But beside that you can store in a local hash which id is belonging to x-y-index of your square. so you can query that information. And why are you not creating your id out of that two x y informations you need for storing the wall/exit-information?

  7. #7
    Join Date
    Aug 2010
    Posts
    62
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSignalMapper and argument problems

    And why are you not creating your id out of that two x y informations?
    because the matrix of buttons is indexed with two integers...
    even if I store the status of the buttons in a member of a QPushButton-derived object (and not in a dedicated integer matrix) , I have the problem of choosing the value that has to be assigned to a button depending on the selected tool...the "tool variable" (integer variable that stores the tool choosen by the user) cannot be included into the matrix of button. Infact it doesn't make sense to store the tool into the button matrix obect because they have no logical relationship between them...

  8. #8
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QSignalMapper and argument problems

    Quote Originally Posted by harmodrew View Post
    because the matrix of buttons is indexed with two integers...
    Qt Code:
    1. int x,y;
    2. QString id = QString("%1-%2").arg(x).arg(y);
    3. // in the slot:
    4. int x, y;
    5. QStringList tmp = id.split("-");
    6. x = tmp.at(0).toInt();
    7. y = tmp.at(1).toInt();
    To copy to clipboard, switch view to plain text mode 
    or you create a local
    Qt Code:
    1. QHash< QString (id), QPair< int (x), int (y) > > mapping;
    To copy to clipboard, switch view to plain text mode 

    I have the problem of choosing the value that has to be assigned to a button depending on the selected tool...
    but you can surely access that information from your slot! there must be a pointer in your class, beside how would you do it when creating the connection, if you have there access you also have it in your slot.

  9. #9
    Join Date
    Aug 2010
    Posts
    62
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSignalMapper and argument problems

    No, I cannot access to the tool object:

    mymacros.h:
    Qt Code:
    1. #ifndef MYMACROS_H
    2. #define MYMACROS_H
    3.  
    4. #define WALL 3
    5. #define ENTRY 2
    6. #define EXIT 1
    7. #define REMOVE 0
    8.  
    9. #endif // MYMACROS_H
    To copy to clipboard, switch view to plain text mode 

    tool.h:
    Qt Code:
    1. #ifndef TOOL_H
    2. #define TOOL_H
    3. #include <QObject>
    4.  
    5. class Tool : public QObject
    6. {
    7. Q_OBJECT
    8. int Type;
    9.  
    10. public slots:
    11. void SetWall();
    12. void SetEntry();
    13. void SetExit();
    14. void SetRemove();
    15. };
    16. #endif // TOOL_H
    To copy to clipboard, switch view to plain text mode 

    tool.cpp:
    Qt Code:
    1. #include "tool.h"
    2. #include "mymacros.h"
    3.  
    4. void Tool:: SetWall()
    5. {
    6. Type = WALL;
    7. }
    8.  
    9. void Tool :: SetEntry()
    10. {
    11. Type = ENTRY;
    12. }
    13.  
    14. void Tool::SetExit()
    15. {
    16. Type = EXIT;
    17. }
    18.  
    19. void Tool::SetRemove()
    20. {
    21. Type = REMOVE;
    22. }
    To copy to clipboard, switch view to plain text mode 

    toolbar.h:
    Qt Code:
    1. #ifndef TOOLBAR_H
    2. #define TOOLBAR_H
    3. #include <mainwindow.h>
    4.  
    5. void CreateToolBar(MainWindow* win, Tool *tool);
    6.  
    7. #endif // TOOLBAR_H
    To copy to clipboard, switch view to plain text mode 

    toolbar.cpp:
    Qt Code:
    1. #include "toolbar.h"
    2. #include "ui_mainwindow.h"
    3. #include "tool.h"
    4.  
    5. void CreateToolBar(MainWindow *win, Tool *tool)
    6. {
    7. QToolBar *ToolBar = new QToolBar("ToolBar");
    8.  
    9. QAction *WallButton=new QAction(QIcon(QApplication::applicationDirPath().append("/img/Wall.bmp")),"Wall",win);
    10. QAction *EntryButton=new QAction(QIcon(QApplication::applicationDirPath().append("/img/Entry.bmp")),"Entry",win);
    11. QAction *ExitButton=new QAction(QIcon(QApplication::applicationDirPath().append("/img/Exit.bmp")),"Exit",win);
    12. QAction *RemoveButton=new QAction(QIcon(QApplication::applicationDirPath().append("/img/Remove.bmp")),"Remove",win);
    13.  
    14. ToolBar->insertAction(EntryButton,WallButton);
    15. ToolBar->insertAction(ExitButton,EntryButton);
    16. ToolBar->insertAction(RemoveButton,ExitButton);
    17. ToolBar->insertAction(0,RemoveButton);
    18.  
    19. win->addToolBar(ToolBar);
    20.  
    21. // here I connect the buttons of the toolbar with the tool SLOTs (which change its status)
    22. win->connect(WallButton,SIGNAL(triggered()),tool, SLOT(SetWall()));
    23. win->connect(RemoveButton,SIGNAL(triggered()),tool, SLOT(SetRemove()));
    24. win->connect(ExitButton,SIGNAL(triggered()),tool, SLOT(SetExit()));
    25. win->connect(EntryButton,SIGNAL(triggered()),tool, SLOT(SetEntry()));
    26. }
    To copy to clipboard, switch view to plain text mode 

    so when the user chooses a button on the toolbar the status is stored in the integer member of Tool.
    moreover in the mainwindow constructor I create a tool object which is passed to CreateToolbar to associate the toolbar buttons to the tool SLOTs:

    part of the main.cpp:
    Qt Code:
    1. //...
    2. Tool *tool = new Tool;
    3. MainWindow w(tool);
    4. //...
    To copy to clipboard, switch view to plain text mode 

    mainwindowcpp:
    Qt Code:
    1. #include "mainwindow.h"
    2. #include "ui_mainwindow.h"
    3. #include "toolbar.h"
    4. #include "tool.h"
    5.  
    6. //MainWindow constructor
    7. MainWindow::MainWindow(Tool *tool, QWidget *parent) :
    8. QMainWindow(parent),
    9. ui(new Ui::MainWindow)
    10. {
    11. ui->setupUi(this);
    12. CreateToolBar(this, tool);
    13. }
    14.  
    15. MainWindow::~MainWindow()
    16. {
    17. delete ui;
    18. }
    To copy to clipboard, switch view to plain text mode 

    so the tool is declared in the main and is accessible only in the MainWindow constructor, not in the ButtonMatrix object (which is declared in the main)

  10. #10
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QSignalMapper and argument problems

    Ehm, you really should reconsider your design...
    A simple hack:
    Qt Code:
    1. // in MainWindow add a private variable
    2. Tool *m_tool;
    3.  
    4. //MainWindow constructor
    5. MainWindow::MainWindow(Tool *tool, QWidget *parent) :
    6. QMainWindow(parent),
    7. ui(new Ui::MainWindow)
    8. {
    9. ui->setupUi(this);
    10. CreateToolBar(this, tool);
    11. m_tool = tool; // add this
    12. }
    To copy to clipboard, switch view to plain text mode 
    now you can access tool via m_tool in your main window. (BUT that is really no good design!!!)

  11. #11
    Join Date
    Aug 2010
    Posts
    62
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSignalMapper and argument problems

    ok, I'll take a look to the design (I was doing it right now)
    thanks

  12. #12
    Join Date
    Aug 2010
    Posts
    62
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSignalMapper and argument problems

    I've changed something in my code. Now the mainwindow class is:

    Qt Code:
    1. mainwindow.h
    2. #ifndef MAINWINDOW_H
    3. #define MAINWINDOW_H
    4.  
    5. #include <QMainWindow>
    6. #include <QPushButton>
    7. #include "tool.h"
    8. #include "buttonmatrix.h"
    9. #include <QString>
    10.  
    11. namespace Ui {
    12. class MainWindow;
    13. }
    14.  
    15. class MainWindow : public QMainWindow
    16. {
    17. Q_OBJECT
    18. private:
    19. Ui::MainWindow *ui;
    20. Tool *tool;
    21. ButtonMatrix *buttonMatrix;
    22. QToolBar *toolBar;
    23. QString PathToIcons;
    24.  
    25. public:
    26. explicit MainWindow(int inputnr, int inputnc, QString path_to_icons,QWidget *parent = 0);
    27. ~MainWindow();
    28. void CreateToolBar();
    29. void CreateButtonMatrix(int nrow, int ncol);
    30. void InstanceTool();
    31. public slots:
    32. void SetMatrixItem(const QString & ID);
    33. };
    To copy to clipboard, switch view to plain text mode 


    now I have to set properly the buttons parent which should be the window. I'd make it in che ButtonMatrix constructor (buttons is the pointer to the QPushButton matrix)
    Qt Code:
    1. ButtonMatrix::ButtonMatrix(QWidget *win, int nr, int nc)
    2. {
    3. //...
    4. for (int i=0; i<nrow; i++)
    5. {
    6. for (int j=0; j<ncol; j++)
    7. {
    8. //...
    9. buttons[i][j].setParent(win); // <---
    10. //...
    11. }
    12. }
    13. //...
    14. }
    To copy to clipboard, switch view to plain text mode 

    commenting this row the buttons are shown each in a single window, indipendent from the mainwindow. while, if I uncomment the row the matrix is shown but, when I close the program, I gain a program crash (tre program doesn't quit properly)...

  13. #13
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSignalMapper and argument problems

    How are you creating your matrix?

    Actually, looking at your header file, why do you have a method called CreateButtonMatrix (with the name stating it creates a matrix) but takes a row and column parameter? From the parameter list it seems it (confusingly) creates a single button, not a matrix?

  14. #14
    Join Date
    Aug 2010
    Posts
    62
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSignalMapper and argument problems

    one of the members of MainWindow is, as you see, a ButtonMatrix pointer. the ButtonMatrix object is declared as follows:
    buttonmatrix.h:
    Qt Code:
    1. #ifndef BUTTONMATRIX_H
    2. #define BUTTONMATRIX_H
    3.  
    4. #include <QPushButton>
    5. #include <QSignalMapper>
    6. #include <QString>
    7. #include <QObject>
    8.  
    9. class ButtonMatrix : public QObject
    10. {
    11. Q_OBJECT
    12. private:
    13. QPushButton **buttons; // this is private so out of the ButtonMatrix object it is not accessible
    14. int **status;
    15. int nrow;
    16. int ncol;
    17. QSignalMapper *signalMapper;
    18. public:
    19. ButtonMatrix(){}
    20. ButtonMatrix(QWidget* win, int nrow, int ncol);
    21. ~ButtonMatrix();
    22. void Show();
    23. void SetNRow(int nr);
    24. void SetNCol(int nc);
    25. void GenerateMatrix();
    26. void SetBackground(int i, int j, QString aux);
    27. };
    28.  
    29.  
    30. #endif // BUTTONMATRIX_H
    To copy to clipboard, switch view to plain text mode 

    as commented in the code, the ButtonMatrix object has a member pointer which points the QPushButton matrix in the heap. of course all methods of the ButtonMatrix object can access the buttons pointer. From a MainWindow method I cannot access directly the buttons pointer but only the private ButtonMatrix object. So I need a function of ButtonMatrix which can be called from MainWindow to setup the buttons pointer:

    Qt Code:
    1. void MainWindow::CreateButtonMatrix(int nrow, int ncol)
    2. {
    3. buttonMatrix->SetNRow(nrow);
    4. buttonMatrix->SetNCol(ncol);
    5. buttonMatrix->GenerateMatrix();
    6. }
    To copy to clipboard, switch view to plain text mode 

    GenerateMatrix uses previously setted ncol and nrow to instance buttons and status pointers of the ButtonMatrix object:
    Qt Code:
    1. void ButtonMatrix::GenerateMatrix()
    2. {
    3. buttons = new QPushButton*[nrow];
    4. status = new int*[nrow];
    5. for (int i=0; i<nrow; i++)
    6. {
    7. buttons[i] = new QPushButton[ncol];
    8. status[i] = new int[ncol];
    9. }
    10.  
    11. }
    To copy to clipboard, switch view to plain text mode 

  15. #15
    Join Date
    Aug 2010
    Posts
    62
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QSignalMapper and argument problems

    The error comes up even if i pass to the ButtonMatrix constructor a frame instead of the mainwindow...

Similar Threads

  1. Replies: 4
    Last Post: 9th June 2010, 07:46
  2. double QSignalMapper with QTcpServer/QTcpSocket
    By radeberger in forum Qt Programming
    Replies: 5
    Last Post: 5th May 2010, 18:46
  3. help with QSignalMapper and actions
    By andreime in forum Newbie
    Replies: 1
    Last Post: 9th August 2009, 18:24
  4. ? about QSignalMapper
    By JimDaniel in forum Qt Programming
    Replies: 1
    Last Post: 13th January 2008, 21:21
  5. QSignalMapper question: SIGNAL 2 int's
    By vonCZ in forum Newbie
    Replies: 5
    Last Post: 20th July 2007, 10:02

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.