Reputation: 1217
I have a custom widget that I want to add to a QTextEdit (via drag/drop) and then allow the user to double-click on the widget to open a separate edit window.
Right now I have it to where I can drag the widget onto the QTextEdit and an image is added to represent the widget in the document. This is done via a wrapper class that implements QTextObjectInterface.
Now I need to figure out how to handle mouse events so that when the user clicks in the image, the program knows to bring up a custom edit GUI.
Roughly what I have right now is,
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;
}
and then, in my custom QTextEdit class I have
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);
}
}
Upvotes: 3
Views: 841
Reputation: 1217
Ok, after playing around I managed something that works. I'm not sure if it's the best solution, though. I guess I was hoping for something that would more directly give me the object that was clicked on. As you can image, this solution gets annoying as I start to add many custom QTextObjects since I will need a bunch of if ... else if ... statements
Basically, since I already have my own subclass of QTextEdit, I implemented my own handler for 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);
}
}
}
Upvotes: 2