【发布时间】:2014-03-12 10:41:10
【问题描述】:
我在 Qt 4.7 中工作,我的对话框中有一个 QWidget 对象。我需要遍历每个孩子并将当前文本提取到 QStringList 中。每个其他对象都是 QCheckBox,其余的是 QComboBoxes(我只需要两者的文本部分)。到目前为止,我能想到的唯一方法是使用 children() 函数将它们作为 QObject* 并将它们转换,如下所示:
QStringList textlist;
for(int i = 0; i < ui->myWidget->children().size(); i++)
{
if(i % 2 == 0)
{
QCheckBox *q = (QCheckBox *)ui->myWidget->children().at(i);
textlist.append(q->text());
}
else
{
QComboBox *q = (QComboBox *)ui->myWidget->children().at(i);
textlist.append(q->currentText());
}
}
但是,当我尝试使用它时,它可以正常构建和编译,但在运行时会崩溃。我查了一下,这两个类都是 QObject 的子类(尽管间接通过 QAbstractButton 和 QWidget),它是列表 ui->myWidget->children() 中对象的类型,所以我觉得它们应该能够以这种方式进行转换.我以前没有在这种事情上做过很多工作,所以我不确定是否有更好的方法来做到这一点。如果有人有任何想法,将不胜感激。谢谢!
更新:所以,我无法以这种方式或使用 qobject_cast 进行强制转换。然而,我发现我可以从 QObject 转到 QWidget,并且我认为我应该能够使用 dynamic_cast 从 QWidget 转到所需的对象,但这也不起作用。现在我有这个:
QStringList textlist;
for(int i = 0; i < ui->myWidget->children().size(); i++)
{
QWidget *qw = qobject_cast<QWidget*>(ui->myWidget->children().at(i)
if(i % 2 == 0)
{
QComboBox *q = dynamic_cast<QComboBox*>(qw);
if(q)
{
textlist.append(q->text());
}
}
else
{
QCheckBox *q = dynamic_cast<QCheckBox*>(qw);
if(q)
{
textlist.append(q->currentText());
}
}
}
如果有人有任何想法,我将不胜感激。谢谢。
UPDATE2:我还没有在网上找到太多对此有帮助的东西,所以我也不妨问一下,是否有办法在不强制转换的情况下执行此操作,即直接从 QWidget 中以原始类型获取对象,我也很感激。我对我目前的策略或任何事情都不满意,这只是我能想到的唯一方法——我会采取任何在这一点上有效的方法。
【问题讨论】:
-
使用
qobject_cast<QComboBox*>(ptr)而不是您正在使用的 C 样式转换,并在访问文本之前检查转换是否成功。您使用 C 风格转换的方式非常危险,因为如果转换失败,则不会发出警告。对于失败的 C 风格转换,当您尝试使用指针时,充其量只会崩溃。在最坏的情况下,您会得到无声的数据损坏。 -
@Slavik81 有什么技巧可以让它发挥作用吗?它给了我诸如“无法从'重载功能'转换为'QCheckBox *'”之类的错误
-
@Slavik81 别在意我的评论,这只是我的一个愚蠢的错字。谢谢!
-
一般来说,避免在 C++ 代码中强制转换 C 风格,并且永远不要将它与 OOP 对象一起使用。请注意,指向 same 对象实例的指针可能具有不同的值,具体取决于 pointer 的类型。