嗨:)我正在尝试为自制的RPG创建一个角色表生成器:)我在调试一个奇怪的段错误时遇到了一些麻烦。
究竟发生了什么:
我尝试了什么:
以下是代码:
void CGenerator::updateSkillBoxes()
{
qDebug() << "updateSkillBoxes() started";
//First we remove
int skillNum=_skillI.size();
for(int i=0;i<skillNum;i++)
{
delete(_skillI.takeAt(0));
delete(_skillInputLayout.takeAt(0));
delete(_skillInputBox.takeAt(0));
}
//Clean skillGrid
QLayoutItem *child;
while ((child = _skillGrid->takeAt(0)) != 0)
{
delete child->widget();
delete child;
}
delete _skillGrid;
_skillGrid = new QGridLayout;
for(int i=0;i<_c->getSkill().size();i++)
{
CUSkill *skill = _c->getSkill()[i];
QPointer<QGridLayout> tmpLayout = new QGridLayout;
QPointer<QGroupBox> tmpBox = new QGroupBox;
//Recreate new input
QPointer<CSkillInput> tmpInput = new CSkillInput(d->getSkillNameList(), d->getSkillIdList());
tmpInput->createPerkInput(d->getUsablePerk(skill->getParam("id"), skill->getParam("level").toInt()),
_c->getPerkNumberForSkill(i));
tmpInput->updateInput(skill);
_skillI.append(tmpInput);
//Add everything to the gridlayout
tmpLayout->addWidget(new QLabel("Nom"), 0, 0);
tmpLayout->addWidget(new QLabel("Niveau"), 0, 1);
tmpLayout->addWidget(new QLabel("Spécial"), 0, 2);
tmpLayout->addWidget(new QLabel("Vitesse"), 0, 3);
tmpLayout->addWidget(new QLabel("Type"), 0, 4);
tmpLayout->addWidget(_skillI[i]->level, 1, 1);
tmpLayout->addWidget(_skillI[i]->special, 1, 2);
tmpLayout->addWidget(_skillI[i]->speed, 1, 3);
tmpLayout->addWidget(_skillI[i]->type, 1, 4);
tmpLayout->addWidget(_skillI[i]->name,1, 0);
//Now we add the perks (they have been filled with createPerkInput() earlier
for(int j=0;j<_skillI[i]->perkList.size();j++)
{
tmpLayout->addWidget(_skillI[i]->perkList[j], 2+j, 0);
tmpLayout->addWidget(_skillI[i]->perkLevel[j], 2+j, 1);
tmpLayout->addWidget(_skillI[i]->perkDesc[j], 2+j, 2, 1, -1);
}
//I'm not actually sure i need to access those later, but just to be sure i'll put them somewhere
_skillInputLayout.append(tmpLayout);
_skillInputBox.append(tmpBox);
_skillInputBox[i]->setLayout(_skillInputLayout[i]);
if(i%2 == 0)//We want to put 2 skills by line (cuz it's fancier), so ... different case
{
_skillGrid->addWidget(_skillInputBox[i], i/2, 0, 1, 1, Qt::AlignTop);
}
else
{
_skillGrid->addWidget(_skillInputBox[i], (i-1)/2, 1, 1 , 1, Qt::AlignTop);
}
connect(_skillI[i]->name, SIGNAL(currentIndexChanged(int)), this, SLOT(onSkillChanged()));
}
_skillBox->setLayout(_skillGrid);
qDebug() << "updateSkillBoxes() finished";
}
void CGenerator::onSkillChanged()
{
qDebug() << "onSkillChanged() started";
//We need to find which skill has been updated !
for(int i=0;i<_skillI.size();i++)
{
QString newId = _skillI[i]->name->itemData(_skillI[i]->name->currentIndex()).toString();
if(newId != _c->getSkill()[i]->getParam("id"))
{
_c->updateSkill(i, newId);
CSkillInput *input;
input = _skillI[i];
_c->setSkillParam(i, "level", QString::number(input->level->value()));
_c->setSkillParam(i, "special", input->special->itemData(input->special->currentIndex()).toString());
_c->updatePerkNumber(i, _c->getPerkNumberForSkill(i));
updateSkillBoxes();
}
}
qDebug() << "onSkillChanged() finished";
}
CSkillInput代码:
CSkillInput::CSkillInput(QStringList skillName, QStringList skillId)
{
name = new QComboBox;
for(int i=0;i<skillName.size();i++)
{
name->addItem(skillName[i], skillId[i]);
}
speed = new QComboBox;
speed->addItem("Rapide","f");
speed->addItem("Moyen", "m");
speed->addItem("Lent", "s");
speed->setEnabled(false);
type = new QComboBox;
type->addItem("Martial", "w");
type->addItem("Magique", "m");
type->addItem("Divers", "d");
type->setEnabled(false);
special = new QComboBox;
special->addItem("Rien", "n");
special->addItem("Talent", "t");
special->addItem("Don", "g");
level = new QSpinBox;
level->setMaximum(10);
}
CSkillInput::~CSkillInput()
{
this->name->disconnect();
}
void CSkillInput::createPerkInput(QList<CPerk *> perks, qint32 perkNumber)
{
//First we need to make a list of the perks name
for(int i=0;i<perkNumber;i++)
{
//Kinda ugly but it's because we need to generate differents object
QComboBox *tmpList = new QComboBox;
for(int i=0;i<perks.size();i++)
{
tmpList->addItem(perks[i]->getParamStr("name"), perks[i]->getParamStr("id"));
}
QSpinBox *tmpLevel = new QSpinBox;
QLineEdit *tmpDesc = new QLineEdit;
tmpLevel->setValue(perks[0]->getParamInt("level"));
tmpLevel->setReadOnly(true);
tmpDesc->setText(perks[0]->getParamStr("desc"));
tmpDesc->setToolTip(perks[0]->getParamStr("desc"));
perkList << tmpList;
perkLevel << tmpLevel;
perkDesc << tmpDesc;
}
}
void CSkillInput::updateInput(CUSkill *skill)
{
if(skill->getParam("id") != name->itemData(name->currentIndex()))
{
name->setCurrentIndex(name->findData(skill->getParam("id")));
}
level->setValue(skill->getParam("level").toInt());
speed->setCurrentIndex(speed->findData(skill->getParam("speed")));
special->setCurrentIndex(special->findData(skill->getParam("special")));
type->setCurrentIndex(type->findData(skill->getParam("type")));
}
标题(为了清晰起见,删除了CGenerator中的一些不相关的内容)
class CSkillInput : public QObject
{
Q_OBJECT
public:
CSkillInput(QStringList skillName, QStringList skillId);
~CSkillInput();
void createPerkInput(QList<CPerk *> perks, qint32 perkNumber);
void updateInput(CUSkill *skill);
QPointer<QComboBox> name;
QPointer<QComboBox> speed;
QPointer<QComboBox> type;
QPointer<QComboBox> special;
QPointer<QSpinBox> level;
QList<QPointer<QComboBox > > perkList;
QList<QPointer<QSpinBox > > perkLevel;
QList<QPointer<QLineEdit > > perkDesc;
};
class CGenerator : public QWidget
{
Q_OBJECT
public:
CGenerator(CData *data);
CData *d;
private:
CCharacter *_c;
QGridLayout *_skillGrid;
QGroupBox *_skillBox;
QList<QPointer<QGridLayout> > _skillInputLayout;
QList<QPointer<QGroupBox> > _skillInputBox;
QList<QPointer<CSkillInput> > _skillI;
private slots:
void onSkillChanged();
void updateSkillBoxes();
};
快速图解释我的用户界面:http://i.stack.imgur.com/SDHE2.png
最后,我在segfault上的gdb堆栈:
(gdb) bt
#0 QComboBoxPrivate::itemText (this=this@entry=0xbf2540, index=...) at widgets/qcombobox.cpp:1287
#1 0x00007ffff769e58f in QComboBoxPrivate::_q_emitCurrentIndexChanged (this=this@entry=0xbf2540, index=...)
at widgets/qcombobox.cpp:1279
#2 0x00007ffff769e8eb in QComboBoxPrivate::setCurrentIndex (this=this@entry=0xbf2540, mi=...) at widgets/qcombobox.cpp:2049
#3 0x00007ffff769eb4f in QComboBox::setCurrentIndex (this=this@entry=0xca4450, index=index@entry=2) at widgets/qcombobox.cpp:2025
#4 0x00007ffff76a2f06 in QComboBox::wheelEvent (this=0xca4450, e=0x7fffffffd7e0) at widgets/qcombobox.cpp:3096
#5 0x00007ffff7306748 in QWidget::event (this=0xca4450, event=0x7fffffffd7e0) at kernel/qwidget.cpp:8775
#6 0x00007ffff72b348c in QApplicationPrivate::notify_helper (this=this@entry=0x659590, receiver=receiver@entry=0xca4450,
e=e@entry=0x7fffffffd7e0) at kernel/qapplication.cpp:4570
#7 0x00007ffff72bb4fb in QApplication::notify (this=<optimized out>, receiver=0xca4450, e=0x7fffffffd7e0)
at kernel/qapplication.cpp:4168
#8 0x00007ffff6d8371d in QCoreApplication::notifyInternal (this=0x7fffffffe130, receiver=0xca4450, event=0x7fffffffd7e0)
at kernel/qcoreapplication.cpp:955
#9 0x00007ffff732cb49 in sendSpontaneousEvent (event=<optimized out>, receiver=<optimized out>)
at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:234
#10 QETWidget::translateWheelEvent (this=0x7fffffffd7e0, global_x=12526912, global_y=12486272, delta=12750704, buttons=...,
modifiers=..., orient=Qt::Vertical) at kernel/qapplication_x11.cpp:4578
#11 0x00007ffff73309c8 in QETWidget::translateMouseEvent (this=this@entry=0x7fffffffe0b0, event=event@entry=0x7fffffffdc70)
at kernel/qapplication_x11.cpp:4355
#12 0x00007ffff732ee2c in QApplication::x11ProcessEvent (this=0x7fffffffe130, event=event@entry=0x7fffffffdc70)
at kernel/qapplication_x11.cpp:3663
#13 0x00007ffff7357ed2 in x11EventSourceDispatch (s=0x65c320, callback=0x0, user_data=0x0) at kernel/qguieventdispatcher_glib.cpp:146
#14 0x00007ffff56f8c5d in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#15 0x00007ffff56f8f48 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#16 0x00007ffff56f8ffc in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#17 0x00007ffff6db2d1d in QEventDispatcherGlib::processEvents (this=0x65add0, flags=...) at kernel/qeventdispatcher_glib.cpp:425
#18 0x00007ffff7357f96 in QGuiEventDispatcherGlib::processEvents (this=<optimized out>, flags=...)
at kernel/qguieventdispatcher_glib.cpp:204
#19 0x00007ffff6d82271 in QEventLoop::processEvents (this=this@entry=0x7fffffffe050, flags=...) at kernel/qeventloop.cpp:149
---Type <return> to continue, or q <return> to quit---
#20 0x00007ffff6d825d5 in QEventLoop::exec (this=this@entry=0x7fffffffe050, flags=...) at kernel/qeventloop.cpp:204
#21 0x00007ffff6d88059 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1227
#22 0x0000000000408ad5 in main (argc=1, argv=0x7fffffffe238) at ../../../../code/kustom/kustom-sheet-creator/main.cpp:34