在QTextEdit中自定义QTextObject的自定义鼠标交互

时间:2014-03-20 15:50:21

标签: qt qtextedit

我有一个自定义小部件,我想添加到QTextEdit(通过拖放),然后允许用户双击小部件以打开一个单独的编辑窗口。

现在我可以将小部件拖到QTextEdit上,并添加一个图像来表示文档中的小部件。这是通过实现QTextObjectInterface的包装类完成的。

现在我需要弄清楚如何处理鼠标事件,以便当用户点击图像时,程序知道要调出自定义编辑GUI。

我现在大概是,

class MyWidget : public QWidget
{ ... }

class MyWidgetWrapper : public QObject, QTextObjectInterface
{
    Q_OBJECT
    Q_INTERFACES(QTextObjectInterface)
    ....

    void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format)
    {
        MyWidgetWrapper *tmp = qvariant_cast<MyWidgetWrapper*>(format.property(1));
        painter->drawImage(rect, tmp->mMyWidget.getImage());
    }

    private:
    MyWidget mMyWidget;
}

然后,在我的自定义QTextEdit类中,我有

bool MyTextEdit::initialize()
{
    MyWidgetWrapper *tmp = new MyWidgetWrapper();
    document()->documentLayout()->registerHandler(MyWidgetWrapperFormat, tmp);
    return true;
}

void MyTextEdit::insertFromMimeData(const QMimeData *source)
{
    if(source->hasFormat("application/x-MyWidgetWrapper"))
    {
        MyWidgetWrapper *widgetWrapper = new MyWidgetWrapper(this);

    QTextCharFormat charFormat;
    charFormat.setObjectType(MyWidgetWrapperFormat);
    charFormat.setProperty(MyWidgetWrapperData, QVariant::fromValue(widgetWrapper));

    QTextCursor cursor = textCursor();
    cursor.insertText(QString(QChar::ObjectReplacementCharacter), charFormat);
    setTextCursor(cursor);
    }
}

1 个答案:

答案 0 :(得分:1)

好的,在玩完之后我管理了一些有用的东西。不过,我不确定它是不是最好的解决方案。我想我希望能够更直接地给我点击的对象。正如你可以想象的那样,当我开始添加许多自定义QTextObjects时,这个解决方案会变得烦人,因为我需要一堆if ... else if ...语句

基本上,因为我已经有了自己的QTextEdit子类,所以我为mouseDoubleClickEvent实现了自己的处理程序

void MyTextEdit::mouseDoubleClickEvent(QMouseEvent *event)
{
    QPoint eventPos = event->pos();
    QTextCursor cursor = cursorForPosition(eventPos);

    // now check to see if we've moved the cursor to the space
    // before or after the actual click location
    QRect rect = cursorRect();
    if(rect.x() < eventPos.x())
        cursor.movePosition(QTextCursor::Right);

    // charFormat is for the object BEFORE the 
    // cursor postion
    int type = cursor.charFormat().objectType();
    if(type == MyWidgetWrapperFormat)
    {
        MyWidgetWrapper *ed = qvariant_cast<MyWidgetWrapper*>(cursor.charFormat().property(1));

        mFileDialog->setFileMode(QFileDialog::ExistingFile);
        mFileDialog->setNameFilter("Images (*.bmp *.jpg)");

        if(mFileDialog->exec())
        {
            QStringList filenames = mFileDialog->selectedFiles();
            QString filename = filenames.at(0);
            QImage image(filename);
            ed->MyWidget()->setImage(image);
        }
    }
}