2016-07-04 5 views
0

QIODevice와 같이 사용하기 위해 QTextEdit 주위에 래퍼를 작성했습니다. QTextEdit이 같은 여러 래퍼를 사용할 수 있기를 원하므로 각 래퍼마다 다른 텍스트 색을 사용할 수 있습니다.어떻게 QSharedPointer를 삭제할 수 있습니까?

이 래퍼를 스레드로부터 보호하기 위해 QTextEdit의 사용을 보호하기 위해 QMutex를 추가했습니다. 하지만 하나의 QTextEdit를 보호하기 위해 하나의 뮤텍스 만 사용해야한다고 생각했습니다.

다음 구현으로 QSharedPointer를 사용하여 QTextEdit을 보호합니다.

texteditiodevice.h 나는 QMutex이 삭제됩니다 그래서 내가 mutexes 매핑에서 QSharedPointer 인스턴스를 제거 할 수있는 알고 싶어

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; 
} 

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. 당신의 도움에 대한

감사

+0

그렇게 할 수 없기 때문에 아키텍처를 다시 생각해야합니다. [QWidgets은 재진입이 불가능하며 메인 스레드에서만 사용해야합니다.] (http://doc.qt.io/qt-5/threads-qobject.html). 이 문제를 해결하면 더 이상 뮤텍스 (단 하나의 스레드)가 필요하지 않으므로 문제가 해결됩니다! – dydil

+0

쓰기 데이터는 슬롯에서 호출되므로 GUI 스레드에서 호출됩니다. 그러나 동시에 두 개의 신호가 방출되면 어떻게 될까요? – AMDG

+0

개체가 주 스레드에 있고 신호가 다른 스레드에서 방출 된 경우 신호는 나중에 주 스레드 이벤트 루프에 의해 처리되도록 대기열에 넣어 지므로 뮤텍스를 걱정할 필요가 없습니다. 그러나 자동 (기본값) 또는 대기중인 연결을 사용하여 신호를 연결 한 경우에만 가능합니다. 위의 링크에서 자세한 내용을 보려면 "스레드 간 신호 및 슬롯"섹션을 참조하십시오. – dydil

답변

1

만큼 공유 포인터가 정적 mutexes지도에서와 같이, 그것은 할당이 해제되지 않을 것이며, mutexes의 수명이 프로그램의 수명이다.

뮤텍스를 실제로 삭제하려면 mutexes 매핑에서 제거해야합니다.

+0

또는'mutexes' 맵에서'QWeakPointer'를 사용하십시오. 하지만 개체가 삭제 된 후에도 null 포인터에 대한 QWeakPointer는 여전히 맵에 남아있을 것이라고 생각합니다. –

+0

귀하의 요지를 이해합니다. 내가 명확하지 않은 것 같아요, 내가 mutexes 매핑에서 뮤텍스를 삭제할 수 있어야 할 때에 대한 조언을 원합니다. – AMDG