Results 1 to 8 of 8

Thread: Thread Implementation

  1. #1
    Join Date
    Aug 2011
    Posts
    19
    Thanks
    12
    Qt products
    Qt4
    Platforms
    Unix/X11

    Smile Thread Implementation

    In a nutshell... my question is: How do you set up the signals and slots of objects that go on different threads?

    I have a function that has to run over and over seperate from my main GUI application (A joystick polling function).

    When it comes to connecting the signals and slots of my joystick reader to my main GUI, would I do something like this?
    Qt Code:
    1. class JoystickPoller : public QThread
    2. {
    3. /* implement all QThread functions here,
    4.   set up some custom signals as well */
    5. }
    To copy to clipboard, switch view to plain text mode 

    And then in my main GUI do something like this?

    Qt Code:
    1. JoystickPoller* poller = new JoystickPoller();
    2. connect( poller, SIGNAL( NewJoystickInfo( JoystickData ) ),
    3. this, SLOT( HandleNewJoyStickInfo( JoystickData ) ) );
    To copy to clipboard, switch view to plain text mode 

    Would that be how you set up 2 threads to safely signal and slot with each other?

    Thanks in advance to anyone who answers.

    And I know Mr. Wysota's always on it! Thank you Wysota. You've answered like 80 of my questions now!

  2. #2
    Join Date
    Oct 2010
    Posts
    55
    Thanks
    1
    Thanked 11 Times in 10 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    9

    Default Re: Thread Implementation

    Do you really need to use threads for this? What does the JoystickPoller class look like?

  3. The following user says thank you to helloworld for this useful post:

    bruceariggs (17th October 2011)

  4. #3
    Join Date
    Aug 2011
    Posts
    19
    Thanks
    12
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Thread Implementation

    Well,

    It's not really a JoystickPoller, it's actually event based, and it does a blocking GET for input, which just sits there until it gets input. That's why I put it in a seperate thread.

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Thread Implementation

    Where does it read its data from?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #5
    Join Date
    Aug 2011
    Posts
    19
    Thanks
    12
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Thread Implementation

    Okay, here's the code for my reader

    The file being read is /dev/input/js0, it's a file that is created by Linux and joystick drivers when a joystick is plugged in. If you have multiple joysticks, there'd be js1, js2, js3... etc. etc. We're only ever going to have 1 joystick plugged in.

    First thing to know, it's always set to a Logitech joystick right now, because we only have that joystick at the moment. So it will always get into readLogitechJoystick.

    This code is working fine at the moment. I actually did figure out the thread safe signal/slot stuff.

    But I always love advice. I know C++ really well, but I don't know linux hardware stuff hardly at all.

    I don't like the way I'm doing an infinite loop for this event based device, and I don't like that I'm using ifstream, because I don't think read() is a blocking call?

    Here's the .h

    Qt Code:
    1. #ifndef JOYSTICKREADER_H
    2. #define JOYSTICKREADER_H
    3.  
    4. #include <iostream>
    5. #include <fstream>
    6. #include <QThread>
    7.  
    8. #include "JoystickData.h"
    9. #include "Joystick.h"
    10.  
    11. using std::ifstream;
    12. using DataStore::JoystickData;
    13.  
    14. class JoystickReader : public QThread
    15. {
    16. Q_OBJECT
    17.  
    18. public:
    19.  
    20. enum JoystickModel
    21. {
    22. LOGITECH = 0,
    23. OFFICIAL
    24. };
    25.  
    26. JoystickReader(QObject *parent = 0, JoystickModel joyType=LOGITECH );
    27.  
    28. ~JoystickReader();
    29.  
    30. void run();
    31.  
    32. signals:
    33.  
    34. void sendJoystick( const Joystick newJoystick );
    35.  
    36. private:
    37.  
    38. enum LogitechJoystickCommandType
    39. {
    40. LOGITECH_BUTTON = 1,
    41. LOGITECH_JOYSTICK = 2
    42. };
    43.  
    44. enum LogitechJoystickDirection
    45. {
    46. LOGITECH_AXIS_X = 0,
    47. LOGITECH_AXIS_Y = 1
    48. };
    49.  
    50. enum LogitechJoystickPress
    51. {
    52. LOGITECH_RELEASE = 0,
    53. LOGITECH_PRESS = 1
    54. };
    55.  
    56. enum LogitechButtonValue
    57. {
    58. LOGITECH_DEADMAN = 0,
    59. LOGITECH_DOWN = 1,
    60. LOGITECH_UP = 2,
    61. LOGITECH_LEFT = 3,
    62. LOGITECH_RIGHT = 4
    63. };
    64.  
    65. // The file reader
    66. ifstream fd;
    67.  
    68. // Which joystick we're using
    69. JoystickModel joystickType;
    70.  
    71. // the temp Joystick we'll be constantly writing into
    72. Joystick joystick;
    73.  
    74. // Whether a button is pressed or released
    75. char buttonPress;
    76.  
    77. // The magnitude of the joystick press
    78. char magnitude;
    79.  
    80. // Whether it's a button press or a joystick movement
    81. char commandType;
    82.  
    83. // More details on a command type
    84. char messageClarify;
    85.  
    86. void readLogitechJoystick();
    87.  
    88. void readOfficialJoystick();
    89.  
    90. void handleLogitechButtonRelease();
    91.  
    92. void handleLogitechButtonPress();
    93.  
    94. void handleLogitechJoystickMovement();
    95. };
    96.  
    97. #endif // JOYSTICKREADER_H
    To copy to clipboard, switch view to plain text mode 


    And here's the .cpp

    Qt Code:
    1. #include "JoystickReader.h"
    2.  
    3. JoystickReader::JoystickReader(QObject *parent, JoystickModel joyType ) :
    4. QThread(parent)
    5. {
    6. fd.open( "/dev/input/js0", ifstream::in | ifstream::binary );
    7. joystickType = joyType;
    8. }
    9.  
    10. JoystickReader::~JoystickReader()
    11. {
    12. fd.close();
    13. }
    14.  
    15. void JoystickReader::run()
    16. {
    17. if( joystickType == LOGITECH )
    18. {
    19. readLogitechJoystick();
    20. }
    21. else
    22. {
    23. readOfficialJoystick();
    24. }
    25. }
    26.  
    27. void JoystickReader::readLogitechJoystick()
    28. {
    29. // These variables aren't used in our program, THEY DON'T HAVE SOULS!
    30. char unknown, timeChar, timeChar2, timeChar3;
    31. unknown = timeChar = timeChar2 = timeChar3 = 0;
    32. int myTime = 0;
    33.  
    34. // Initialize the important variables (the ones with souls)
    35. buttonPress = magnitude = commandType = messageClarify = 0;
    36. joystick.setXPosition( 0 );
    37. joystick.setYPosition( 0 );
    38.  
    39. // FOR- -EH- -VER
    40. while( 1 )
    41. {
    42. if( fd.is_open() )
    43. {
    44. // Read in the data
    45. fd.read(&unknown, sizeof(char));
    46. fd.read(&timeChar, sizeof(char));
    47. fd.read(&timeChar2, sizeof(char));
    48. fd.read(&timeChar3, sizeof(char));
    49. fd.read(&buttonPress, sizeof(char));
    50. fd.read(&magnitude, sizeof(char));
    51. fd.read(&commandType, sizeof(char));
    52. fd.read(&messageClarify, sizeof(char));
    53.  
    54. // With their powers combined, they are the current time!
    55. myTime = (((timeChar3<<16)&0x00FF0000)
    56. + ((timeChar2<<8)&0x0000FF00))
    57. + (timeChar & 0x000000FF);
    58.  
    59. // Joystick is obviously connected
    60. joystick.setConnectionState( true );
    61.  
    62. // Is this a button press update?
    63. if( commandType == LOGITECH_BUTTON )
    64. {
    65. // Is this button released or pressed?
    66. if( buttonPress == LOGITECH_RELEASE )
    67. {
    68. handleLogitechButtonRelease();
    69. }
    70. else if( buttonPress == LOGITECH_PRESS )
    71. {
    72. handleLogitechButtonPress();
    73. }
    74. }
    75. // Else this is a joystick movement update
    76. else if( commandType == LOGITECH_JOYSTICK )
    77. {
    78. handleLogitechJoystickMovement();
    79. }
    80. }
    81. }
    82. }
    83.  
    84. void JoystickReader::handleLogitechButtonRelease()
    85. {
    86. // Which button?
    87. switch( messageClarify )
    88. {
    89. case LOGITECH_DEADMAN:
    90. {
    91. // deadman released
    92. joystick.setDeadmanState( false );
    93. break;
    94. }
    95. case LOGITECH_DOWN:// down released
    96. case LOGITECH_UP:// up released
    97. case LOGITECH_LEFT:// left released
    98. case LOGITECH_RIGHT:// right released
    99. {
    100. joystick.setButtonPressed( Joystick::NONE );
    101. break;
    102. }
    103. default:
    104. {
    105. // It was one of the buttons we don't care about, do nothing
    106. break;
    107. }
    108. };
    109. }
    110.  
    111. void JoystickReader::handleLogitechButtonPress()
    112. {
    113. // Which button?
    114. switch( messageClarify )
    115. {
    116. case LOGITECH_DEADMAN:
    117. {
    118. // deadman pressed
    119. joystick.setDeadmanState( true );
    120. break;
    121. }
    122. case LOGITECH_DOWN:// down pressed
    123. {
    124. joystick.setButtonPressed( Joystick::DOWN );
    125. break;
    126. }
    127. case LOGITECH_UP:// up pressed
    128. {
    129. joystick.setButtonPressed( Joystick::UP );
    130. break;
    131. }
    132. case LOGITECH_LEFT:// left pressed
    133. {
    134. joystick.setButtonPressed( Joystick::LEFT );
    135. break;
    136. }
    137. case LOGITECH_RIGHT:// right pressed
    138. {
    139. joystick.setButtonPressed( Joystick::RIGHT );
    140. break;
    141. }
    142. default:
    143. {
    144. // Do nothing
    145. break;
    146. }
    147. };
    148. }
    149.  
    150. void JoystickReader::handleLogitechJoystickMovement()
    151. {
    152. // Which axis?
    153. switch( messageClarify )
    154. {
    155. case LOGITECH_AXIS_X: // X Axis
    156. {
    157. joystick.setXPosition( magnitude );
    158. break;
    159. }
    160. case LOGITECH_AXIS_Y: // Y Axis
    161. {
    162. joystick.setYPosition( magnitude );
    163. break;
    164. }
    165. default:
    166. {
    167. break;
    168. }
    169. }
    170. }
    171.  
    172. void JoystickReader::readOfficialJoystick()
    173. {
    174. // Currently does nothing!
    175. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by bruceariggs; 17th October 2011 at 17:43. Reason: Explaining in great detail!

  7. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Thread Implementation

    You don't need threads then. Just use QSocketNotifier or QLocalSocket on /dev/input/js0 and use signals and slots.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. The following user says thank you to wysota for this useful post:

    bruceariggs (17th October 2011)

  9. #7
    Join Date
    Oct 2011
    Location
    Australia
    Posts
    29
    Thanks
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: Thread Implementation

    I actually did figure out the thread safe signal/slot stuff.
    And?

    But I always love advice.
    So do I!

  10. #8
    Join Date
    Aug 2011
    Posts
    19
    Thanks
    12
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Thread Implementation

    Yeap! This worked out just fine for me.

    Qt Code:
    1. // Create the JoystickReader thread
    2. JoystickReader *myReader = new JoystickReader(
    3. 0, DisplaySettingsData::getInstance()->getMiscSettings()
    4. .getJoystickModel() );
    5.  
    6. // Connect the thread signal to the DataStore slot
    7. QObject::connect( myReader,
    8. SIGNAL( setNewJoystick(const Joystick&) ),
    9. JoystickControl::getInstance(),
    10. SLOT(setJoystick(const Joystick&)) );
    11.  
    12. // Start the thread
    13. myReader->start();
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Replies: 1
    Last Post: 28th July 2011, 17:03
  2. Replies: 5
    Last Post: 22nd February 2011, 21:21
  3. Replies: 16
    Last Post: 7th October 2009, 08:17
  4. Replies: 10
    Last Post: 22nd July 2009, 23:52
  5. Confusing in thread implementation
    By santosh.kumar in forum Qt Programming
    Replies: 0
    Last Post: 16th May 2007, 11:07

Tags for this Thread

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.