【问题标题】:How can I delete a QSharedPointer如何删除 QSharedPointer
【发布时间】:2016-11-06 05:27:50
【问题描述】:

我已经为 QTextEdit 编写了一个包装器,以便像 QIODevice 一样使用它。我希望能够在同一个 QTextEdit 中使用多个包装器,因此我可以为每个包装器使用不同的文本颜色。

为了使这个包装器线程安全,我添加了一个 QMutex 来保护 QTextEdit 的使用。但我在想我必须只使用一个互斥锁来保护一个 QTextEdit。

我最终得到以下实现,使用 QSharedPointer 来保护 QTextEdit。

texteditiodevice.h

class TextEditIODevice : public QIODevice
{
    Q_OBJECT

public:
    TextEditIODevice(QTextEdit * qTextEdit, QColor color, QObject * parent);

    virtual ~TextEditIODevice();

protected:
    qint64 readData(char *data, qint64 maxlen);

    qint64 writeData(const char *data, qint64 len);

private:
    /**
     * @brief Pointer to QTextEdit
     */
    QPointer<QTextEdit> textEdit;

    /**
     * @brief Text color
     */
    QColor color;

    /**
     * @brief Shared pointer to QTextEdit associated mutex
     */
    QSharedPointer<QMutex> mutex;

    /**
     * @brief Storage for QTextEdit associated mutexes
     */
    static QMap<QPointer<QTextEdit>, QSharedPointer<QMutex>> mutexes;
};

texteditiodevice.cpp

QMap<QPointer<QTextEdit>, QSharedPointer<QMutex>> TextEditIODevice::mutexes;

TextEditIODevice::TextEditIODevice(QTextEdit * qTextEdit, QColor color, QObject * parent) :
    QIODevice(parent),
    textEdit(qTextEdit),
    color(color)
{
    open(QIODevice::WriteOnly | QIODevice::Text);

    qRegisterMetaType<QTextCharFormat>("QTextCharFormat");
    qRegisterMetaType<QTextBlock>("QTextBlock");
    qRegisterMetaType<QTextCursor>("QTextCursor");

    if(mutexes.contains(textEdit))
        mutex = mutexes[textEdit];
    else
    {
        mutex = QSharedPointer<QMutex>(new QMutex());
        mutexes.insert(textEdit, mutex);
    }
}

TextEditIODevice::~TextEditIODevice()
{
}

qint64 TextEditIODevice::readData(char *data, qint64 maxlen)
{
    Q_UNUSED(data);
    Q_UNUSED(maxlen);
    return 0;
}



qint64 TextEditIODevice::writeData(const char *data, qint64 len)
{
    if(textEdit)
    {
        mutex->lock();
        const QColor lastColor = textEdit->textColor();
        textEdit->setTextColor(color);
        textEdit->append(QString(data));
        textEdit->setTextColor(lastColor);
        mutex->unlock();
    }

    return len;
}

我想知道在哪里可以从mutexes 映射中删除 QSharedPointer 实例,以便删除 QMutex。

感谢您的帮助

【问题讨论】:

  • 您必须重新考虑您的架构,因为您无法做到这一点。 QWidgets are not reentrant and must be used only from the main thread。解决此问题后,您将不再需要互斥锁(只有一个线程),因此问题将得到解决!
  • 写入数据是在一个槽中调用的,所以是从GUI线程调用的。但是如果同时发出两个信号呢?
  • 如果您的对象在主线程中并且从另一个线程发出信号,则该信号将排队等待稍后由主线程事件循环处理,因此无需使用互斥锁 :) .但是,这仅在您使用自动(默认)或排队连接连接信号时才适用。您可以查看我上面提供的链接中的“跨线程的信号和插槽”部分以获取更多信息。

标签: c++ qt qsharedpointer


【解决方案1】:

只要共享指针在静态mutexes映射中,就永远不会被释放,mutexes的生命周期就是程序的生命周期。

如果你想真正删除一个互斥体,你必须将它从mutexes 映射中删除。

【讨论】:

  • 或在mutexes 映射中使用QWeakPointer。但我认为QWeakPointer 到 null 仍然会留在地图中,即使在删除对象后,您也必须清除空指针。
  • 我明白你的意思。我想我并不清楚,我想要一些关于何时应该/可以从互斥体映射中删除互斥体的建议。
猜你喜欢
  • 2019-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 2012-09-19
  • 1970-01-01
  • 2017-06-09
相关资源
最近更新 更多