大家好,我使用QTableView開發的程式,在單獨的測驗工程中運行良好,在正式的應用程式工程里運行崩潰,請問是何原因?
代碼中的資料模式類代碼如下:
class FormulaListModel : public QAbstractTableModel
{
typedef struct
{
QString op1_name;
QString op2_name;
QString op;
bool isEnable;
}FORMULA, *PFORMULA;
Q_OBJECT
public:
FormulaListModel(QObject *parent);
~FormulaListModel();
/*Implement the necessary virtual function of QAbstractListModel*/
int rowCount(const QModelIndex & parent = QModelIndex()) const;
int columnCount(const QModelIndex & parent = QModelIndex()) const;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
private:
QVector<PFORMULA> m_lsFormula;
};
FormulaListModel::FormulaListModel(QObject *parent)
: QAbstractTableModel(parent)
{
int i;
for (i = 0;i < 40;i ++)
{
PFORMULA formula = new FORMULA;
formula->isEnable = true;
formula->op = "+";
formula->op1_name = QString("%1").arg(i);
formula->op2_name = QString("%1").arg(50 - i);
m_lsFormula.append(formula);
}
}
FormulaListModel::~FormulaListModel()
{
foreach(PFORMULA f, m_lsFormula)
{
if (f)
{
delete f;
}
}
m_lsFormula.clear();
}
int FormulaListModel::rowCount(const QModelIndex & parent) const
{
return m_lsFormula.count();
}
int FormulaListModel::columnCount(const QModelIndex & parent) const
{
return 4;
}
QVariant FormulaListModel::data(const QModelIndex & index, int role) const
{
switch(role)
{
case Qt::EditRole:
{
int r = index.row();
int c = index.column();
PFORMULA pf = m_lsFormula[r];
switch(c)
{
case 0:
return pf->isEnable;
case 1:
return pf->op1_name;
case 2:
return pf->op;
case 3:
return pf->op2_name;
}
}
case Qt::DisplayRole:
{
int c = index.column();
int r = index.row();
PFORMULA pf = m_lsFormula[r];
QStringList lsStr;
switch(c)
{
case 0:
return "IsUsed";
case 1:
case 3:
lsStr << "1";
lsStr << "2";
return lsStr;
case 2:
lsStr << "+";
lsStr << "-";
return lsStr;
}
}
case Qt::DecorationRole:
{
QColor clr(Qt::transparent);
return clr;
}
case Qt::SizeHintRole:
return QSize(130, 16);
case Qt::FontRole:
{
QFont font;
font.setBold(true);
return font;
}
case Qt::BackgroundRole:
{
QBrush brush(Qt::transparent);
return brush;
}
case Qt::TextAlignmentRole:
{
return Qt::AlignHCenter;
}
case Qt::CheckStateRole:
{
return Qt::Checked;
}
case Qt::TextColorRole:
{
QColor clr(Qt::black);
return clr;
}
case Qt::ToolTipRole:
{
return "Formula List";
}
}
}
表格單元代理類代碼如下:
class CheckBoxDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
CheckBoxDelegate(QObject *parent);
~CheckBoxDelegate();
/*****如果使用代理而不是editor工廠來提供editor,則下列虛函式必須要多載********/
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option,
const QModelIndex & index)const;
void setEditorData(QWidget * editor, const QModelIndex & index) const;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const;
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
protected:
private:
};
CheckBoxDelegate::CheckBoxDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
CheckBoxDelegate::~CheckBoxDelegate()
{
}
QWidget * CheckBoxDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option,
const QModelIndex & index)const
{
QVariant value = index.model()->data(index, Qt::DisplayRole);
if (index.column() == 0)
{
QCheckBox * pBox = new QCheckBox(parent);
pBox->setText(value.toString());
return pBox;
}
else
{
QComboBox * pBox = new QComboBox(parent);
pBox->addItems(value.toStringList());
return pBox;
}
}
void CheckBoxDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const
{
QVariant value = index.model()->data(index, Qt::EditRole);
if (index.column() == 0)
{
bool checked = value.toBool();
QCheckBox * pBox = static_cast<QCheckBox *>(editor);
if (pBox)
{
pBox->setChecked(checked);
}
}
else
{
QString str = index.model()->data(index, Qt::EditRole).toString();
qDebug() << index << str;
QComboBox * pBox = static_cast<QComboBox *>(editor);
if (pBox)
{
pBox->setCurrentIndex(pBox->findText(str));
}
}
}
void CheckBoxDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QRect rc = option.rect;
editor->setGeometry(rc);
}
void CheckBoxDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
{
if (index.column() == 0)
{
QCheckBox * pBox = static_cast<QCheckBox *>(editor);
pBox->update();
bool checked = pBox->isChecked();
model->setData(index, checked, Qt::EditRole);
}
else
{
QComboBox * pBox = static_cast<QComboBox *>(editor);
pBox->update();
QString str = pBox->currentText();
model->setData(index, str, Qt::EditRole);
}
}
void CheckBoxDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
//畫控制元件本身
int x = option.rect.x();
int y = option.rect.y();
painter->setBackgroundMode(Qt::TransparentMode);
QVariant value = index.model()->data(index, Qt::DisplayRole);
if (index.column() == 0)
{
bool checked = value.toBool();
QStyleOptionButton style;
style.rect = QRect(x, y + 8, 12, 12);
style.state |= QStyle::State_Enabled;
style.state |= checked ? QStyle::State_On : QStyle::State_Off;
QApplication::style()->drawControl(QStyle::CE_CheckBox, &style, painter);
}
else
{
QStyleOptionComplex style;
style.rect = QRect(x, y + 8, 12, 12);
style.state = QStyle::State_HasFocus;
style.state |= QStyle::State_Enabled;
QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &style, painter);
}
//寫字
//QFont font;
//font.setFamily("Microsoft YaHei");
//font.setPixelSize(10);
//font.setWeight(QFont::Bold);
//painter->setFont(font);
//painter->setPen(Qt::red);
//painter->drawText(x + 16, y - 12, "ABCD");
}
呼叫部分代碼:
m_pModel2 = new FormulaListModel(this);
ui.lvContainer->setModel(m_pModel2);
ui.lvContainer->setShowGrid(false);
//m_pModel2->setColumnCount(4);
//pModel->setRowCount(50);
QHeaderView * pHeader = ui.lvContainer->horizontalHeader();
pHeader->hide();
pHeader = ui.lvContainer->verticalHeader();
pHeader->hide();
//設定列寬
ui.lvContainer->setColumnWidth(0, 80);
//ui.lvContainer->setItemDelegateForColumn(0, new CheckBoxDelegate(this));
ui.lvContainer->setColumnWidth(1, 150);
ui.lvContainer->setColumnWidth(2, 150);
ui.lvContainer->setColumnWidth(3, 150);
//ui.lvContainer->setItemDelegateForColumn(1, new ComboBoxDelegate(this));
//ui.lvContainer->setItemDelegateForColumn(2, new ComboBoxDelegate(this));
//ui.lvContainer->setItemDelegateForColumn(3, new ComboBoxDelegate(this));
ui.lvContainer->setItemDelegate(new CheckBoxDelegate(this));
for (int i = 0;i < m_pModel2->rowCount();i ++)
{
ui.lvContainer->openPersistentEditor(m_pModel2->index(i, 0));
ui.lvContainer->openPersistentEditor(m_pModel2->index(i, 1));
ui.lvContainer->openPersistentEditor(m_pModel2->index(i, 2));
ui.lvContainer->openPersistentEditor(m_pModel2->index(i, 3));
}
ui.lvContainer->updateGeometry();
現象:使用滑鼠滾輪移動表格,程式崩潰。
在測驗程式中不會崩潰,而真正程式中會崩潰。代碼都是一樣的,唯一區別是:測驗程式主視窗是QDialog類,而崩潰程式主視窗是QMainWindow類,在彈出的QDialog視窗中使用的表格視圖。
請高手幫忙看看,謝謝!
uj5u.com熱心網友回復:
你給一個完整的代碼吧,誰有那么多時間去猜的除錯代碼。一個完整的代碼,給一些測驗資料就可以了,別人拷貝就可以跑崩潰的
uj5u.com熱心網友回復:
QVariant FormulaListModel::data(const QModelIndex & index, int role) 這個函式有問題的。switch陳述句缺少default選項,可能會導致訪問例外而Crash。
加個如下:
default:
return QVariant();
uj5u.com熱心網友回復:
感謝以上二位,原帖說法有誤,其實測驗程式中一樣會崩潰,只是當時未測驗完全,沒發現而已。真正的崩潰原因已找到,是因為我用的QCheckBox不支持滑鼠滾輪操作,只要在QCheckBox上操作滾輪,程式就會崩潰,解決辦法就是加一個eventFilter,針對QCheckBox過濾掉不支持的滑鼠滾輪操作即可。
現在想進一步改善性能,當滑鼠在QCheckBox上滾輪操作時,想把這個事件轉移到表格上,讓表格滾動,還沒找到辦法。
uj5u.com熱心網友回復:
QCheckBox上滑鼠滾輪?轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/128001.html
標籤:Qt
