On 9/4/20 2:40 PM, Kyle Edwards wrote:
After some more investigation, I've learned more about the nature of
the problem.
The createEditor() override returns a button which, when clicked,
opens a file dialog (through QFileDialog::getOpenFileName() - this
will be important in a bit). The opening of this dialog causes the
editor to lose focus, which result in QAbstractItemDelegate emitting
its closeEditor() signal, which in turn destroys the editor. The
destroying of the editor also attempts to delete the file dialog,
since it's a child of the editor. However, the file dialog was
allocated on the stack by QFileDialog::getOpenFileName(). So,
attempting to delete the stack-allocated dialog results in a crash.
So I guess the question is, how do I prevent QAbstractItemDelegate
from emitting closeEditor() when the file dialog opens? Either that or
prevent closeEditor() from actually closing the editor... I see
something in QAbstractItemView::closeEditor() about an editor being
"persistent", does that have anything to do with this?
I now have a minimum working test case:
// BEGIN
#include<QItemDelegate>
#include<QApplication>
#include<QFileDialog>
#include<QLineEdit>
#include<QResizeEvent>
#include<QStandardItemModel>
#include<QToolButton>
#include<QTreeView>
#include<QWidget>
classTestEdit: publicQLineEdit
{
Q_OBJECT
public:
TestEdit(QWidget*parent= nullptr);
voidresizeEvent(QResizeEvent*e) override;
public slots:
voidchooseFile();
private:
QToolButton* toolButton;
};
TestEdit::TestEdit(QWidget*parent)
: QLineEdit(parent)
{
this->toolButton= newQToolButton(this);
this->toolButton->setText("...");
QObject::connect(this->toolButton, SIGNAL(clicked(bool)), this,
SLOT(chooseFile()));
}
voidTestEdit::resizeEvent(QResizeEvent*e)
{
// make the tool button fit on the right side
inth= e->size().height();
// move the line edit to make room for the tool button
this->setContentsMargins(0, 0, h, 0);
// put the tool button in its place
this->toolButton->resize(h, h);
this->toolButton->move(this->width() - h, 0);
}
voidTestEdit::chooseFile()
{
autopath= QFileDialog::getOpenFileName(this, "title", QString(), QString(),
nullptr, QFileDialog::DontResolveSymlinks);
if(!path.isEmpty()) {
this->setText(path);
}
}
classTestItemDelegate: publicQItemDelegate
{
Q_OBJECT
public:
QWidget*createEditor(QWidget*parent, constQStyleOptionViewItem&option,
constQModelIndex&index) constoverride;
};
QWidget*TestItemDelegate::createEditor(QWidget*parent,
constQStyleOptionViewItem&option, constQModelIndex&index) const
{
returnnewTestEdit(parent);
}
intmain(intargc, char**argv)
{
QApplicationapp(argc, argv);
QWidgetwindow;
QTreeViewview(&window);
auto* model= newQStandardItemModel;
view.setModel(model);
model->insertRow(0);
model->insertColumn(0);
model->setData(model->index(0, 0), "Hello");
view.setItemDelegate(newTestItemDelegate);
window.show();
returnapp.exec();
}
#include"qttest.moc"
// END
Run the program, double click the "Hello" item, a line editor will
appear, click the button on the right to open the dialog, and then the
invalid delete happens.
Kyle
_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest