从QTreeWidget继承的自定义窗口小部件在销毁时崩溃了?

时间:2017-12-14 04:23:23

标签: c++ qt widget

最近我遇到了一些关于QT的问题。由于我们有很多自定义小部件(继承自QT的基本小部件,如QWidget,QTreeWidget ......),它们在运行时运行良好,但是,它很容易崩溃当退出程序或破坏它们时,我不知道在实现从基本小部件继承的小部件时是否有任何错误或不适当。 这是一个例子:

ChatTreeWidget.cpp:

#include "ChatTreeWidget.h"
#include <QPicture>
#include <QDebug>
ChatTreeWidget::ChatTreeWidget(QWidget *parent)
:QTreeWidget(parent)
{
    setRootIsDecorated(false);
    setIndentation(0);
    setHeaderHidden(true);
    setIconSize(QSize(30, 30));
    setFocusPolicy(Qt::NoFocus);


    setObjectName(QString("chatTreeWidget"));
    setStyleSheet("#chatTreeWidget{border:0px;}"
        "QTreeWidget::item{border-bottom:1px solid #d9d9d9;padding-left:0px;}"
        "QTreeWidget::item:hover{background-color: #def0ff;}"
        "QTreeWidget::item:selected{background-color:#c2e2fd;}");

    connect(this, &QTreeWidget::itemExpanded, this, [=](QTreeWidgetItem *item)
    {
        auto indexvar = item->data(0, Qt::UserRole).toInt();
        indexvar -= 10000;
        if (indexvar > m_iconList.size() || indexvar < 0)
            return;
        auto lbl = m_iconList.at(indexvar);
        lbl->setPixmap(QPixmap(":/Widgets/Resources/chattree/sanjiao1.png"));
    });

    connect(this, &QTreeWidget::itemCollapsed, this, [=](QTreeWidgetItem *item)
    {
        auto indexvar = item->data(0, Qt::UserRole).toInt();
        indexvar -= 10000;
        if (indexvar > m_iconList.size() || indexvar < 0)
            return;
        auto lbl = m_iconList.at(indexvar);
        lbl->setPixmap(QPixmap(":/Widgets/Resources/chattree/sanjiao2.png"));
    });

    connect(this, &QTreeWidget::itemClicked, this, [=](QTreeWidgetItem *item, int column) {
        auto indexvar = item->data(0, Qt::UserRole).toInt();
        indexvar -= 10000;
        if (indexvar > m_iconList.size() || indexvar < 0)
            return;
        if (item->isExpanded())
        {
            setItemExpanded(item, false);
        }
        else
        {
            setItemExpanded(item, true);
        }

    });
    setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
}


    ChatTreeWidget::~ChatTreeWidget()
{
    qDebug() << "123123";
}


QTreeWidgetItem* ChatTreeWidget::addTreeWidgetTopItem(QString str)
{
    return insertTreeWidgetTopItem(topLevelItemCount(), str);
}

QTreeWidgetItem* ChatTreeWidget::insertTreeWidgetTopItem(int index, QString str)
{
    QWidget *widget = new QWidget(this);
    QLabel *textLabel = new QLabel(widget);
    QHBoxLayout *hlayout = new QHBoxLayout(widget);
    QLabel *iconLabel = new QLabel(widget);
    QSpacerItem *spacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

    textLabel->setText(str);

    textLabel->setStyleSheet(u8"font-family: \"Microsoft YaHei\"");
    hlayout->addWidget(textLabel);

    hlayout->addSpacerItem(spacer);

    iconLabel->setPixmap(QPixmap(":/Widgets/Resources/chattree/sanjiao2.png"));

    hlayout->addWidget(iconLabel);

    hlayout->setContentsMargins(5, 0, 10, 0);

    widget->setLayout(hlayout);

    m_iconList.append(iconLabel);
    QTreeWidgetItem *rootItem = new QTreeWidgetItem();
    rootItem->setData(0, Qt::UserRole, m_index);
    rootItem->setSizeHint(0, QSize(30, 30));
    m_index++;
    this->insertTopLevelItem(index, rootItem);
    setItemWidget(rootItem, 0, widget);
    rootItem->setBackground(0, Qt::green);
    setExpandsOnDoubleClick(false);
    return rootItem;
}


void ChatTreeWidget::setRootItemStyleSheet(QTreeWidgetItem *item,QString css)
{
    auto widgets = itemWidget(item, 0);
    widgets->setStyleSheet(css);
}


void ChatTreeWidget::setRootItemStyleSheet(QString css)
{
    for (qint32 i = 0; i < topLevelItemCount(); i++)
    {
        auto rootItem = topLevelItem(i);
        auto widgets = itemWidget(rootItem,0);
        widgets->setStyleSheet(css);
    }
}

这段代码试图实现一个custom-treewidget来显示聊天成员,所以它继承了QTreeWidget(一旦我认为我应该用QTreeView实现它,但是因为我很愚蠢和懒惰,我直接使用了QTreeWidget),并且使用特殊的样式表来更改显示样式。由于它是一个公共窗口小部件,它提供了一些用于添加顶级项目的界面。这是一个示例图像:

enter image description here

当我破坏这个小部件时(我确定这个小部件是来自UI或布局的令牌),甚至有时QT的自动破坏会导致崩溃。它经常发生但不是每次都发生。 破坏小部件的两种主要方式是: 1.将其添加到某个UI,并让它由该UI管理。 2.手工删除:

chatTreeWidget->setParent(0);
chatTreeWidget->disconnect();
chatTreeWidget->deleteLater();

它们都可能导致随机崩溃。 有什么不对吗?或者它只是一个错误? 感谢您提供任何帮助!

0 个答案:

没有答案