c++multithreadingqtqprocessstdthread

QProcess and std::thread - Cannot create children for a parent that is in a different thread


I am getting a run-time message

QObject: Cannot create children for a parent that is in a different thread.

when starting a QProcess in a std::thread. The program runs, but I feel that this message will be trouble, eventually.

I saw this one and this other answers (as well as some in python), which I did not see how to apply to my code.

I am using QtCreator, Qt 6.5 LTS and gcc 11.2.0 in Win10. A minimal working example is below. You will have to create an empty GUI window with QPushButton pushButton. The class definition is:

class MainWindow : public QMainWindow
{
  Q_OBJECT
    
public:
  MainWindow(QWidget *parent = nullptr);
  ~MainWindow();
    
private slots:
  void clicked(bool);
    
private:
  Ui::MainWindow *ui;
    
  void launchNotepad();
   
  std::thread th;
  QProcess process;
};

And the implementation is:

MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)
  , ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(clicked(bool)));
}

MainWindow::~MainWindow()
{
  delete ui;
}

void MainWindow::clicked(bool)
{
  th = std::thread{&MainWindow::launchNotepad,this};
  th.detach();
}

void MainWindow::launchNotepad()
{
  process.start("notepad");
}

When I click on the button, notepad indeed appears and all looks well. But the Application output console in QtCreator gives me the message "Cannot create children...". For reasons beyond this question, I do want to work with std::thread.

My questions:

  1. What is the trouble that I am sure eventually I'll have because of this message ?

  2. How to get rid of it, while keeping using std::thread ?


Solution

  • A QProcess is also a QObject, and each QObject has an associated thread. By default the thread of the QObject is the one that created it. In this case, since it's a member of your own QMainWindow-based class, and will have been created when your main window has been created, it will by default have the same thread as your main window, which is not the thread you are trying to use QProcess from.

    Since QProcess internally creates other QObjects, those objects will have been created in the thread that called process.start(). But that is not the thread that QProcess belongs to. And since QObject parent-child relationships can only work for objects in the same thread, you'll get this debug message from Qt, because QProcess can't properly create the desired sub-objects it wants to create.

    You have three options here to solve this (in increasing order of simplicity and usefulness):

    But this is all way too complicated, because: