Results 1 to 5 of 5

Thread: Strange compilation errors when using "invokeMethod"

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jun 2012
    Location
    Spain
    Posts
    19
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Strange compilation errors when using "invokeMethod"

    Hi,

    I'm renewing an old application by "threading" it. The idea is to deliver a (high) number of simulation tasks to the threads that the computer may have. After reading a lot about threading, I've used a QThreadPool in a "server" class to deliver the tasks. These tasks are implemented in a so-called "client" class. I also want to have information about the evolution of the thread operation, so the "server" class has a GUI where I show information about it, such as the status of the tasks (pending/in progress/completed), a progress bar, etc.

    I've implemented the reporting from the threaded tasks through "invokeMethod", invoking in the "client" class two slots from the "server" class, in a similar way to the example in https://www.walletfox.com/course/qrunnableexample.php.

    However, I'm getting some strange compiler errors:

    * In the two invokeMethod calls ("no matching function for call to 'QMetaObject::invokeMethod(QWidget*&, ...").
    * In "qobjectdefs.h" file ("no type named 'type' in struct std::enable_if<false, bool>'").
    * In the moc file of the client's cpp file!!!

    Probably all may be due to the same error (or errors), but I'm not able to catch. I want to remark that, although I comment the invokeMethod calls, the other errors persist...

    In other posts I've seen that you suggested to delete the moc and ui files, the makefiles, etc. So, I've deleted completely the build folder, and recompiled the project as new. But the errors in the moc file do appear again.

    Any idea? I enclose the h and cpp files for the "client" and "server" classes (although simplifying some irrelevant functions) in case they may help. If you consider necessary to upload all the application, please don't hesitate to ask, and I'll do.

    Thanks!

    Server.h

    Qt Code:
    1. #ifndef SERVERMTH_H
    2. #define SERVERMTH_H
    3.  
    4. #include <QFile>
    5. #include <QFileInfo>
    6. #include <QDialog>
    7. #include <QMessageBox>
    8. #include <QProcess>
    9. #include <QProgressDialog>
    10. #include <QString>
    11. #include <QStringList>
    12. #include <QThreadPool>
    13. #include <QElapsedTimer>
    14. #include "BasicDeclarations.h"
    15. #include "ClientRunnable.h"
    16.  
    17. namespace Ui {
    18. class ServerMTh;
    19. }
    20.  
    21. class ServerMTh : public QDialog
    22. {
    23. Q_OBJECT
    24.  
    25. public:
    26. explicit ServerMTh(QWidget *parent = nullptr, QString designpath = "", QString design = "",
    27. int nbr_injections = 0, QStringList *macro_list = nullptr,
    28. QStringList *trace_list = nullptr);
    29. ~ServerMTh();
    30.  
    31. private slots:
    32. void confirmAbort();
    33. void ClientStarted(int id_client);
    34. void ClientTerminated(int id_client, int client_status);
    35.  
    36. private:
    37. enum
    38. {
    39. INJECTIONNUMBER, INJECTIONSTATUS
    40. };
    41. #define SimulationPending 0
    42. #define SimulationInProgress 1
    43. #define SimulationTerminated 2
    44. #define SimulationError 3
    45.  
    46. Ui::ServerMTh *ui;
    47. bool ForceAbort;
    48. bool Disconnecting;
    49. int return_value;
    50. int NbrInjections, i_progress;
    51. int maxOperativeThreads, InjectingThreads;
    52. int TotalSimulations, SimulationsFinished, SimulationsInProgress;
    53. int *InjectionStatus;
    54. QString Design_Path, Design;
    55. QStringList *macroList, *traceList;
    56. QThreadPool *ThreadPool;
    57. QList<int> ErrorClients;
    58. QElapsedTimer *timerStart, *timerStartSimulation;
    59. qint64 EndOperationTime, EndSimulationTime;
    60.  
    61. void reject();
    62. QString FormatTime(const qint64 time);
    63. int WriteTimeReport(QString fich);
    64. };
    65.  
    66. #endif // SERVERMTH_H
    To copy to clipboard, switch view to plain text mode 

    The two slots that should be invoked by the client are ClientStarted(int id_client) and ClientTerminated(int id_client, int client_status).

    Server.cpp
    Qt Code:
    1. #include <QDir>
    2. #include <QTextStream>
    3. #include "ServerMTh.h"
    4. #include "ui_ServerMTh.h"
    5.  
    6.  
    7. ServerMTh::ServerMTh(QWidget *parent, QString designpath, QString design, int nbr_injections, QStringList *macro_list, QStringList *trace_list) :
    8. QDialog(parent),
    9. ui(new Ui::ServerMTh)
    10. {
    11. ui->setupUi(this);
    12.  
    13. // GUI and other elements setup
    14.  
    15. // 2. Create runnables and launch to threads
    16. for (int i_injection = 0; (i_injection < TotalSimulations); i_injection++)
    17. {
    18. ClientRunnable *Client = new ClientRunnable(this);// The idea is that the client knows the "owner" of ths slots to invoke
    19. Client->ID = i_injection;
    20. Client->Design = Design;
    21. Client->MacroFile = macroList->at(i_injection);
    22. ThreadPool->start(Client);
    23. }
    24. }
    25.  
    26. ServerMTh::~ServerMTh()
    27. {
    28. }
    29.  
    30. void ServerMTh::confirmAbort()
    31. {
    32. ui->progressCancel->setEnabled(false);
    33. QString msg = "Abort injection. Are you sure?";
    34. QMessageBox msgBox(this);
    35. msgBox.setIcon(QMessageBox::Question);
    36. msgBox.setText(msg);
    37. msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    38. msgBox.setDefaultButton(QMessageBox::No);
    39. if (msgBox.exec() == QMessageBox::Yes)
    40. {
    41. ui->progressInfo->setText("Please wait until injections in progress end...");
    42. qApp->processEvents();
    43.  
    44. ThreadPool->clear();
    45. ThreadPool->waitForDone(-1);
    46. Disconnecting = true;
    47. done(-1);
    48. }
    49. else
    50. ui->progressCancel->setEnabled(true);
    51.  
    52. qApp->processEvents();
    53. }
    54.  
    55. void ServerMTh::ClientStarted(int id_client)
    56. {
    57. // Update GUI
    58. }
    59.  
    60. void ServerMTh::ClientTerminated(int id_client, int client_status)
    61. {
    62.  
    63. // Check Modelsim start status
    64. if (client_status == ClientRunnable::KOCLIENTSTART)
    65. {
    66. if (ErrorClients.contains(id_client))
    67. {
    68.  
    69. // Same simulation has produced two errors => Terminate
    70. ThreadPool->clear();
    71. ThreadPool->waitForDone(-1);
    72. Disconnecting = true;
    73. done(-1);
    74. }
    75. else
    76. {
    77.  
    78. // Add the task to the pool
    79. ClientRunnable *Client = new ClientRunnable;
    80. Client->ID = id_client;
    81. Client->Design = Design;
    82. Client->MacroFile = macroList->at(id_client);
    83. ThreadPool->start(Client);
    84. }
    85. }
    86. else
    87. {
    88. if (ErrorClients.contains(id_client))
    89. {
    90.  
    91. // Remove erroneous simulation from the list
    92. ErrorClients.removeAt(ErrorClients.indexOf(id_client));
    93. }
    94.  
    95. // Update GUI
    96.  
    97. if ((TotalSimulations - (SimulationsFinished + SimulationsInProgress)) == 0)
    98. {
    99. ThreadPool->waitForDone(-1);
    100. Disconnecting = true;
    101. done(0);
    102. }
    103. }
    104. }
    105.  
    106. void ServerMTh::reject()
    107. {
    108. if (!Disconnecting)
    109. confirmAbort();
    110. }
    111.  
    112. QString ServerMTh::FormatTime(const qint64 time)
    113. {
    114. return QString("%1:%2:%3").arg((time / 3600000), 2, 10, QChar('0')).arg(((time / 60000) % 60), 2, 10, QChar('0')).arg(((time / 1000) % 60), 2, 10, QChar('0'));
    115. }
    116.  
    117. int ServerMTh::WriteTimeReport(QString fich)
    118. {
    119. return 0;
    120. }
    To copy to clipboard, switch view to plain text mode 

    Client.h
    Qt Code:
    1. #ifndef CLIENT_RUNNABLE_H
    2. #define CLIENT_RUNNABLE_H
    3.  
    4. #include <QObject>
    5. #include <QProcess>
    6. #include <QRunnable>
    7. #include <QString>
    8.  
    9. class ClientRunnable : public QRunnable
    10. {
    11. Q_OBJECT
    12.  
    13. public:
    14. enum
    15. {
    16. OKCLIENTSTART, KOCLIENTSTART
    17. };
    18.  
    19. ClientRunnable(QWidget *parent = nullptr);
    20. int ID;
    21. QString MacroFile, Design;
    22.  
    23. private:
    24. QWidget *Parent;
    25. QString LogFile, TraceFile;
    26. int Status;
    27. QProcess *proc;
    28.  
    29. int CheckLog();
    30. int FindTrace();
    31. int CleanTrace();
    32.  
    33. protected:
    34. void run();
    35. };
    36.  
    37. #endif // CLIENT_RUNNABLE_H
    To copy to clipboard, switch view to plain text mode 

    Client.cpp

    Qt Code:
    1. #include <QArgument>
    2. #include <QDebug>
    3. #include <QDir>
    4. #include <QFile>
    5. #include <QMetaObject>
    6. #include <QStringList>
    7. #include "ClientRunnable.h"
    8.  
    9. ClientRunnable::ClientRunnable(QWidget *parent)
    10. {
    11. Parent = parent;
    12. Status = OKCLIENTSTART;
    13. }
    14.  
    15. void ClientRunnable::run()
    16. {
    17. // Compìler error HERE:
    18. QMetaObject::invokeMethod(Parent, "ClientStarted", Qt::QueuedConnection, Q_ARG(int, ID));
    19. // Note that "Parent" is the server, that is, the owner of the slot invoked
    20.  
    21. // 1. Create process and run
    22. pars << ...;
    23. proc = new QProcess;
    24. if (proc->execute("vsim.exe", pars) < 0)
    25. Status = KOCLIENTSTART;
    26.  
    27. // 2. Check log file
    28. if (Status == OKCLIENTSTART)
    29. {
    30. if (CheckLog() < 0)
    31. Status = KOCLIENTSTART;
    32. }
    33.  
    34. // 3. Compress trace file
    35. if (Status == OKCLIENTSTART)
    36. {
    37. if (FindTrace() < 0)
    38. Status = KOCLIENTSTART;
    39.  
    40. if (Status == OKCLIENTSTART)
    41. {
    42. if (TraceFile != "")
    43. {
    44. if (CleanTrace() < 0)
    45. Status = KOCLIENTSTART;
    46. }
    47. else
    48. Status = KOCLIENTSTART;
    49. }
    50. }
    51.  
    52. // Compìler error HERE too:
    53. QMetaObject::invokeMethod(Parent, "ClientTerminated", Qt::QueuedConnection, Q_ARG(int, ID), Q_ARG(int, Status));
    54.  
    55. if (Status == OKCLIENTSTART)
    56. exit(0);
    57. else
    58. exit(-1);
    59. }
    60.  
    61. int ClientRunnable::CheckLog()
    62. {
    63. return 0;
    64. }
    65.  
    66. int ClientRunnable::FindTrace()
    67. {
    68. return 0;
    69. }
    70.  
    71. int ClientRunnable::CleanTrace()
    72. {
    73. return 0;
    74. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jcbaraza; 7th December 2021 at 21:44.

Similar Threads

  1. Replies: 1
    Last Post: 20th November 2015, 10:02
  2. Replies: 3
    Last Post: 16th March 2015, 07:31
  3. qt cross compilation error "unable to load interpreter"
    By cpalm in forum Qt for Embedded and Mobile
    Replies: 0
    Last Post: 12th July 2011, 10:51
  4. Replies: 4
    Last Post: 26th July 2010, 07:02
  5. Translation QFileDialog standart buttons ("Open"/"Save"/"Cancel")
    By victor.yacovlev in forum Qt Programming
    Replies: 4
    Last Post: 24th January 2008, 19:05

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.