加载从信号槽接收的QStringList值

时间:2017-12-03 07:03:11

标签: c++ qt combobox signals-slots qstringlistmodel

在我的qt c ++应用程序中,QStringList通过信号和插槽机制从一个cpp文件(MainWIndow)发送到另一个cpp文件(Dialog)!我想在界面加载时(在没有按钮点击的情况下)在Dialog.ui的组合框中显示qtringList中的元素!

以下是我的代码

    #include "dialog.h"
    #include "ui_dialog.h"

    Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
    {
    ui->setupUi(this);

    for(int i=0;i<subMessages.size();i++){
    ui->comboBox->addItem(subMessages[i]);

    }
    }

//slot which is used to get the qstringList
    void Dialog::receiveSubMessages(QStringList List){ 
    subMessages=List;

    }

通过插槽(已经验证)成功接收到QStringList。虽然我使用了for循环并尝试显示(如代码中所示)但组合框上没有显示任何内容!我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

我做了这个答案,而不是告诉你如何解决你的问题。 (我觉得我甚至不明白你的实际问题是什么。)

在提问时,如果提供了MCVE,则有机会获得有用的答案。 (请关注此链接。它教会了每个S / W开发人员必须具备的基本技能。我还建议跟进How to debug small programs。)

由于确实理解了你的问题,我做了这样的MCVE。这是代码testQComboBox

#include <QtWidgets>

int main(int argc, char **argv)
{
  // build appl.
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // a QStringList with items
  QStringList items;
  items
    << QString::fromUtf8("first item")
    << QString::fromUtf8("second item")
    << QString::fromUtf8("third item");
  // build GUI
  QDialog dlg;
  QVBoxLayout vBox;
  QComboBox cmbBox;
  cmbBox.addItems(items);
  vBox.addWidget(&cmbBox);
  dlg.setLayout(&vBox);
  dlg.show();
  app.exec();
  // done
  return 0;
}

我在Windows 10(64位)上使用Qt 5.9.2在VS2013中编译了它。这是它的外观:

Snapshot of testQComboBox

如您所见,组合框的使用相当容易 - 没有秘密陷阱门可以使用它。与QComboBox直接相关的实际代码正好是 4 代码行:

  QVBoxLayout vBox;
  QComboBox cmbBox;
  cmbBox.addItems(items);
  vBox.addWidget(&cmbBox);

并且只有一行代码将项目添加到QComboBox

  cmbBox.addItems(items);

注意:

我使用QComboBox::addItems()代替QComboBox::addItem(),因为前者已经内置了一个循环来添加完整的QStringList。它对您在代码Dialog::Dialog()中使用的循环没有任何影响。

所以,最后我敢做以下陈述:

如果你的组合框没有显示项目,那么:

  1. 您从空列表中添加了项目。

  2. 或者,您忘记添加列表中的项目。

  3. 或者,发生了一些非常奇怪的事情。

  4. 我总是打赌1.或2.理由 - 原因仅在于真正的紧急情况(例如Qt安装破坏)。

    关于3.理由:

    我看到很多问题,其中提出了一些无辜的代码,这些代码看起来完全按照它们的应有但声称失败了。最后几乎每次都显示这些线在MCVE中被隔离时工作正常,但它们在原始代码中没有。怎么会发生这种情况?有一些上下文会改变原始程序中代码的行为,或者存在UB - 未定义的行为。其他东西做坏事但不是立即崩溃你的过程(这意味着你很幸运)它会持续一段时间腐败数据越来越多,直到最后一切都完全破裂。调查核心转储根本没有用。因此我推荐How to debug small programs

答案 1 :(得分:1)

为了获得正常工作的代码,您需要将for llop放在您的插槽中:

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

//slot which is used to get the qstringList
void Dialog::receiveSubMessages(QStringList List){ 
    ui->comboBox->addItems (List);
}

如果要在QStringList构造时使用某些Dialog的内容填充comboBox,那么您应该将此列表作为构造函数参数传递:

Dialog::Dialog(QStringList List, QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
    ui->setupUi(this); 
    ui->comboBox->addItems (List);
}

或在Dialog::receiveSubMessages()对象构建后立即致电Dialog

// somewhere in code, where you construct Dialog object
// ...
auto parent = SomeQWidgetDerivedClass (...);
QStringList someStringList {
    "string 1",
    "string 2"
};
// ...
auto dialog {new Dialog ()};

dialog->receiveSubMessages (someStringList);
// ...

您提供的代码永远不会允许您实现所需的结果,因为在您的for对象创建中执行了应该填充QComboBox的{​​{1}}循环。那时你的Dialog是空的。您创建的插槽在构造函数之前未被调用 - 插槽只是一个只能在创建对象后调用的成员函数。如果函数本身是静态的,那么你只能在没有对象的情况下调用成员函数,在这种情况下它肯定不是一个插槽。