0

I am using a Logger window, wich is a simple widget inheriting from QPlainTextEdit.

Now I needed to print several messages at the same time (I made this thread safe with a mutex), but it crashes anyway. This is the message from gdb

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff56c5cb9 in QTextLine::draw(QPainter*, QPointF const&, QTextLayout::FormatRange const*) const ()
from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5

I am using Qt 5.4, but tried Qt 5.7 and the crash persists. Does anyone have a hint? Should I inherit from some other widget?

manatttta
  • 3,054
  • 4
  • 34
  • 72
  • 3
    without code sample we won't be able to help – stryku Jul 14 '16 at 08:06
  • 1
    Make sure you are not calling GUI functions from non-GUI threads. – Alexander Saprykin Jul 14 '16 at 08:08
  • Instead of using a mutex, you will likely do better at serialising the threads by using asynchronous (i.e. default) signal-slot connections. But without a [mcve] it's impossible to know what it is that you're doing. Please [edit] your question to add the smallest complete example that demonstrates the problem. – Toby Speight Jul 14 '16 at 08:14
  • @AlexanderSaprykin yes I am doing that. How do I solve it? Using signal/slots? – manatttta Jul 14 '16 at 08:18
  • @manatttta Yes, you need to use signals and slots. Emit a signal from a thread with the text and catch that signal in your GUI (`Qt` should automatically use a queued signal-slot connection). That way you do not need a mutex ever. – Alexander Saprykin Jul 14 '16 at 08:21
  • @AlexanderSaprykin can I pass a std::string object via the signal/slot interface? – manatttta Jul 14 '16 at 08:53
  • @manatttta Yes, you can, but you need to do some actions: http://stackoverflow.com/questions/7698986/emit-stdstring-with-qt-signal. I would recommend you to use `QString` instead, it also has `QString::fromStdString()` method. – Alexander Saprykin Jul 14 '16 at 09:04

1 Answers1

0

As people have commented above, the issue probably lies in your way of doing things. So here´s the recommended way on how to handle your situation: use QThread, do not use a mutex.

Qt uses the signal/slot for threadsafe communication. An example on how to get you started quickly:

class A : public QObject
{
    Q_OBJECT

    // ...

public slots:
    void run();
}

Any class you want to run in a new thread from another needs a "run" slot, you can call it what you like, but it´s the first function that gets called in the new thread once you start it in the implementation below:

// Create and start the thread
QThread *t = new QThread;
t->start();

// Create an object of your class and move it to the thread
A* a = new A();
a->moveToThread(t);

// Now actually run it in the thread through the signal slot system
QMetaObject::invokeMethod(a, "run", Qt::QueuedConnection);

I hope that made it clear, if you have any questions let me know.

Sir Rogers
  • 345
  • 1
  • 3
  • 10