LINUX.ORG.RU

Проблема с QTreeView

 


0

2

Когда создаешь отдел и добавляешь сотрудника и после этого открываешь вкладку отдела то программа вылетает(вылетает только тогда когда это первая компания). сигнал sigsegv.

//CompanyModel.cpp
#include "CompanyModel.h"
#include "EmployeeDepartmentIcons.h"
#include <QDebug>


CompanyModel::CompanyModel(QObject *parent)
    : QAbstractItemModel(parent){}

QModelIndex CompanyModel::index(int row, int column, const QModelIndex &parent) const {
    if (!hasIndex(row, column, parent))
        return QModelIndex();

    if (!parent.isValid()) {
        return createIndex(row, column, quintptr(-1));
    } else if (parent.internalId() == quintptr(-1)) {
        return createIndex(row, column, parent.row());
    } else {
        return createIndex(row, column, parent.internalId() * 1000 + parent.row());
    }
}

QModelIndex CompanyModel::parent(const QModelIndex &index) const {
    if (!index.isValid())
        return QModelIndex();

    quintptr internalId = index.internalId();
    if (internalId == quintptr(-1))
        return QModelIndex();

    if (internalId < 1000) {
        return createIndex(internalId, 0, quintptr(-1));
    } else {
        int companyIndex = internalId / 1000;
        int departmentIndex = internalId % 1000;
        return createIndex(departmentIndex, 0, companyIndex);
    }
}

int CompanyModel::rowCount(const QModelIndex &parent) const {
    if (!parent.isValid())
        return companies.size();

    if (parent.internalId() == -1) {
        return companies.at(parent.row()).departments.size();
    } else if (parent.internalId() >= 0 && parent.internalId() < companies.size()) {
        return companies.at(parent.internalId()).departments.at(parent.row()).employees.size();
    }

    return 0;
}
int CompanyModel::columnCount(const QModelIndex &parent) const {
    Q_UNUSED(parent);
    return 4;
}

QVariant CompanyModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid())
        return QVariant();

    if (index.internalId() == quintptr(-1)) {
        const Company &company = companies.at(index.row());
        if (role == Qt::DisplayRole && index.column() == 0)
            return company.name;
        else if (role == Qt::DecorationRole && index.column() == 0)
            return company.logo.isNull() ? StaticIcons::companyIcon() : company.logo;
    } else if (index.internalId() < companies.size()) {
        const Department &department = companies.at(index.internalId()).departments.at(index.row());
        if (role == Qt::DisplayRole && index.column() == 0)
            return department.name;
        else if (role == Qt::DecorationRole && index.column() == 0)
            return StaticIcons::departmentIcon();
    } else {
        int companyIndex = index.internalId() / 1000;
        int departmentIndex = index.internalId() % 1000;
        const Employee &employee = companies.at(companyIndex).departments.at(departmentIndex).employees.at(index.row());
        if (role == Qt::DisplayRole) {
            switch (index.column()) {
            case 0: return employee.name;
            case 1: return employee.position;
            case 2: return employee.gender == Gender::Male ? "Мужской" : "Женский";
            }
        } else if (role == Qt::DecorationRole && index.column() == 0) {
            return employee.photo.isNull() ? StaticIcons::employeeIcon() : employee.photo;
        }
    }
    return QVariant();
}

QVariant CompanyModel::headerData(int section, Qt::Orientation orientation, int role) const {
    if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
        switch (section) {
        case 0:
            return QString("ФИО сотрудника");
        case 1:
            return QString("Должность");
        case 2:
            return QString("Пол");
        }
    }
    return QVariant();
}

bool CompanyModel::setData(const QModelIndex &index, const QVariant &value, int role) {
    if (!index.isValid() || role != Qt::EditRole) {
        return false;
    }

    if (index.internalId() == quintptr(-1)) {
        Company &company = companies[index.row()];
        if (index.column() == 0) {
            company.name = value.toString();
            emit dataChanged(index, index);
            return true;
        }
    } else if (index.internalId() < companies.size()) {
        Company &company = companies[index.internalId()];
        Department &department = company.departments[index.row()];
        if (index.column() == 0) {
            department.name = value.toString();
            emit dataChanged(index, index);
            return true;
        }
    } else {
        int companyIndex = index.internalId() / 1000;
        int departmentIndex = index.internalId() % 1000;
        Company &company = companies[companyIndex];
        Department &department = company.departments[departmentIndex];
        Employee &employee = department.employees[index.row()];

        switch (index.column()) {
        case 0:
            employee.name = value.toString();
            break;
        case 1:
            employee.position = value.toString();
            break;
        case 2:
            employee.gender = value.value<Gender>();
            break;
        default:
            return false;
        }

        emit dataChanged(index, index);
        return true;
    }

    return false;
}

Qt::ItemFlags CompanyModel::flags(const QModelIndex &index) const {
    if (!index.isValid()) {
        return Qt::NoItemFlags;
    }
    Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
    if (index.column() >= 0 && index.column() <= 3) {
        flags |= Qt::ItemIsEditable;
    }
    return flags;
}

void CompanyModel::addCompany(const QString &name, const QPixmap &logo) {
    beginInsertRows(QModelIndex(), companies.size(), companies.size());
    companies.append(Company(name, logo));
    endInsertRows();
}

void CompanyModel::addDepartment(int companyIndex, const QString &departmentName) {
    if (companyIndex < 0 || companyIndex >= companies.size()) {
        return;
    }

    Company &company = companies[companyIndex];
    int departmentIndex = company.departments.size();

    beginInsertRows(createIndex(companyIndex, 0, -1), departmentIndex, departmentIndex);
    company.departments.append(Department(departmentName));
    endInsertRows();
}

void CompanyModel::addEmployee(int companyIndex, int departmentIndex, const QString &name, const QString &position, Gender gender, const QPixmap &photo) {
    qDebug() << "Adding employee. Company index:" << companyIndex << "Department index:" << departmentIndex;

    if (companyIndex < 0 || companyIndex >= companies.size()) {
        qDebug() << "Invalid company index:" << companyIndex;
        return;
    }

    Company &company = companies[companyIndex];

    if (departmentIndex < 0 || departmentIndex >= company.departments.size()) {
        qDebug() << "Invalid department index:" << departmentIndex;
        return;
    }

    Department &department = company.departments[departmentIndex];

    qDebug() << "Current number of employees:" << department.employees.size();

    beginInsertRows(createIndex(departmentIndex, 0, companyIndex), department.employees.size(), department.employees.size());
    department.employees.append(Employee(name, position, gender, photo));
    endInsertRows();

    qDebug() << "Employee added successfully. New number of employees:" << department.employees.size();
}

bool CompanyModel::setCompanyLogo(int companyIndex, const QPixmap &logo) {
    if (companyIndex < 0 || companyIndex >= companies.size()) {
        return false;
    }
    companies[companyIndex].logo = logo;
    emit dataChanged(createIndex(companyIndex, 0, -1), createIndex(companyIndex, 0, -1), { Qt::DecorationRole });
    return true;
}

bool CompanyModel::setEmployeePhoto(int companyIndex, int departmentIndex, int employeeIndex, const QPixmap &photo) {
    if (companyIndex < 0 || companyIndex >= companies.size()) {
        return false;
    }
    Company &company = companies[companyIndex];
    if (departmentIndex < 0 || departmentIndex >= company.departments.size()) {
        return false;
    }
    Department &department = company.departments[departmentIndex];
    if (employeeIndex < 0 || employeeIndex >= department.employees.size()) {
        return false;
    }
    department.employees[employeeIndex].photo = photo;
    emit dataChanged(createIndex(employeeIndex, 0, departmentIndex), createIndex(employeeIndex, 0, departmentIndex), { Qt::DecorationRole });
    return true;
}
bool CompanyModel::removeCompany(int companyIndex) {
    if (companyIndex < 0 || companyIndex >= companies.size()) {
        return false;
    }
    beginRemoveRows(QModelIndex(), companyIndex, companyIndex);
    companies.removeAt(companyIndex);
    endRemoveRows();
    return true;
}

bool CompanyModel::removeDepartment(int companyIndex, int departmentIndex) {
    if (companyIndex < 0 || companyIndex >= companies.size()) {
        return false;
    }
    Company &company = companies[companyIndex];
    if (departmentIndex < 0 || departmentIndex >= company.departments.size()) {
        return false;
    }
    beginRemoveRows(createIndex(companyIndex, 0, -1), departmentIndex, departmentIndex);
    company.departments.removeAt(departmentIndex);
    endRemoveRows();
    return true;
}


bool CompanyModel::removeEmployee(int companyIndex, int departmentIndex, int employeeIndex) {
    if (companyIndex < 0 || companyIndex >= companies.size()) {
        return false;
    }
    Company &company = companies[companyIndex];
    if (departmentIndex < 0 || departmentIndex >= company.departments.size()) {
        return false;
    }
    Department &department = company.departments[departmentIndex];
    if (employeeIndex < 0 || employeeIndex >= department.employees.size()) {
        return false;
    }
    beginRemoveRows(createIndex(departmentIndex, 0, companyIndex), employeeIndex, employeeIndex);
    department.employees.removeAt(employeeIndex);
    endRemoveRows();
    return true;
}

bool CompanyModel::moveEmployee(int sourceCompanyIndex, int sourceDepartmentIndex, int sourceEmployeeIndex,
                                int targetCompanyIndex, int targetDepartmentIndex) {
    if (sourceCompanyIndex < 0 || sourceCompanyIndex >= companies.size() ||
        targetCompanyIndex < 0 || targetCompanyIndex >= companies.size()) {
        return false;
    }

    Company &sourceCompany = companies[sourceCompanyIndex];
    Company &targetCompany = companies[targetCompanyIndex];

    if (sourceDepartmentIndex < 0 || sourceDepartmentIndex >= sourceCompany.departments.size() ||
        targetDepartmentIndex < 0 || targetDepartmentIndex >= targetCompany.departments.size()) {
        return false;
    }

    Department &sourceDepartment = sourceCompany.departments[sourceDepartmentIndex];
    Department &targetDepartment = targetCompany.departments[targetDepartmentIndex];

    if (sourceEmployeeIndex < 0 || sourceEmployeeIndex >= sourceDepartment.employees.size()) {
        return false;
    }

    beginMoveRows(createIndex(sourceEmployeeIndex, 0, sourceDepartmentIndex), sourceEmployeeIndex, sourceEmployeeIndex,
                  createIndex(targetDepartmentIndex, 0, targetCompanyIndex), targetDepartment.employees.size());

    Employee employee = sourceDepartment.employees.takeAt(sourceEmployeeIndex);
    targetDepartment.employees.append(employee);

    endMoveRows();
    return true;
}

Перемещено Dimez из general

Ну во 1ых собери с дебагом, и при падении будет более конкретная информация на чём сломалось; во 2ых почисти портянищу до минимального воспроизводимого примера, и вот уже со всем этим сюда, если, конечно, проделывая всё это сам не догадаешься

zurg
()

А какой помощи ты ждёшь запостив сюда эту простыню (нет, никто читать её не будет), при том что это ещё и не весь код (т.е. собрать и погонять нельзя)? gdb и санитайзеры в зубы, вперед.

anonymous
()

Вангую, что где-то выход за пределы массива. Или массив некорректно заполнен или обращение к элементу до заполнения массива или индекс некорректный. А вообще, запусти в дебаге и не мучай голову, хоть увидишь где упало.

Loki13 ★★★★★
()