Qt主界面获取对话框数据

在编写Qt程序的时候,我们常常需要通过对话框来获取用户的输入数据,比如通过文件对话框获取文件的路径,通过颜色对话框获取用户所选择的颜色,这些对话框的类都是Qt帮我们写好了的,调用相应函数就能直接返回用户的输入,比如颜色对话框QColorDialog中有一个静态函数getColor,我们直接调用该函数,便会弹出颜色对话框,等我们选择好颜色并确定,该函数就会返回一个QColor的对象,这个对象就包含了我们之前所选颜色的RGB值了。

然而,很多时候,我们需要创建自己的对话框,我们不能调用现成函数来获取用户输入,本文将提供两种方法,通过对话框来获取用户输入的案例。在此之前,我们先讨论一下显示对话框的两个函数,一个是show(),一个是exec()。show() 显示的是非模态窗口,不会阻塞程序的线程,因此如果你的对话框是创建在栈上,跳出作用域之后,对象便销毁了,因此你会发现对话框一闪而过;如果你用new关键字将对话框创建在堆上,跳出作用域之后对象不能被销毁,但是建立在堆上需要考虑及时释放内存的问题,以免造成内存泄漏。但是能够正常显示窗口不代表能够很方便地获取数据,show()不会阻塞线程,因此可能用户还没来得及输入数据,就已经执行之后的代码了。解决这个问题需要用到信号槽机制,具体解决方案会在下文详细讲解。exec()显示的是模态窗口,它开启了一个事件循环,会阻塞程序的线程,函数返回之后,我们直接可以获取对话框的数据。下面考虑这两种不同的对话框显示方式,提供两种不同的获取对话框数据的方法。

方法一
首先考虑简单的,使用exec()显示对话框。我们定义了一个主界面的类,叫MainWindow,界面包含一个名为btn的按钮(用于跳出对话框)和一个名为label的标签(用于显示从对话框获取的用户输入);我们还定义一个对话框类,界面包含一个名为lineEdit的单行文本框(用于接收用户输入),以及确定和取消按钮(这两个按钮是创建对话框的时候自动生成的)。两个界面如下图:
主界面
对话框界面
关键代码如下:

//in mainwindow.h
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    void showDialog();
};

//in mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //“显示对话框”按钮与显示函数建立信号槽关系
    connect(ui->btn, &QPushButton::clicked, this, &MainWindow::showDialog);
}
MainWindow::~MainWindow(){delete ui;}
void MainWindow::showDialog()
{
    Dialog dialog;
    dialog.exec();
    ui->label->setText(dialog.getinput());
}
//in dialog.h
class Dialog : public QDialog
{
    Q_OBJECT
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
    QString getinput();
private:
    Ui::Dialog *ui;
};

//in dialog.cpp
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}
Dialog::~Dialog(){delete ui;}
QString Dialog::getinput()
{
    QString s = ui->lineEdit->text();
    return s;
}

代码说明:上面的程序还是比较容易理解的,在mainwindow.h和mainwindow.cpp里,先将btn与showDialog建立联系,在showDialog内部创建Dialog对象,并通过exec()显示,由于exec()会阻碍线程,因此待用户输入数据之后再执行后续获取数据的代码,由于我们想获取的dialog内的数据是私有的,因此在Dialog类定义了一个public的getinput()函数(之前还考虑用友元,感觉被自己蠢哭了),间接获取用户的输入,最后将数据显示在主界面的label上面,达到主界面获取对话框数据的目的。
附:方法一源代码

方法二:
上面讨论的是用exec()显示对话框的情况下获取用户输入数据,那如果用show()显示对话框,该如何获取数据呢?由于show()不会开启事件循环,因此如果继续按上面的方法,用户根本来不及输入数据,后续的代码就已经执行了,因此需要用到信号槽机制。思路是这样的:按下对话框的确定按钮后,程序会自动调用QDialog::accept()函数,因此如果我们可以重载accept()函数,在其中发送信号,关联该信号的槽便会响应,我们在槽里面进行数据数据接收。
关键代码如下:

//in mainwindow.h
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    void showDialog();
    void displayData(QString data);
    void accept();
};

//in mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->btn, &QPushButton::clicked, this, &MainWindow::showDialog);
}
MainWindow::~MainWindow(){delete ui;}
void MainWindow::showDialog()
{
    Dialog *dialog = new Dialog(this);
    connect(dialog, &Dialog::receiveData, this, &MainWindow::displayData);
    dialog->show();
}
void MainWindow::displayData(QString data)
{
    ui->label->setText(data);
}
//in dialog.h
class Dialog : public QDialog
{
    Q_OBJECT
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
signals:
    void receiveData(QString s);
private:
    Ui::Dialog *ui;
    void accept();
};

//in dialog.cpp
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}
Dialog::~Dialog(){delete ui;}
void Dialog::accept() //重载accept()
{
    QString data = ui->lineEdit->text();
    emit receiveData(data);  //发送信号给mainwindow
    QDialog::accept();
}

代码说明:用户输入数据后,按下确定按钮,程序会自动调用accept(),因此重载了accept()函数,让其将获取的输入数据作为信号(receiveData是一个信号)通过emit发送给主界面,在mainwindow.cpp,我们信号receiveData和槽displayData进行关联,displayData将接收的数据显示在主界面的label上的。总的来说,数据输入后,先调用accept(),accept()将信号(信号上带有数据)发送给displayData,displayData显示数据。通过信号槽机制,我们看到,即使对话框作为非模态窗口显示,即使其稍纵即逝,我们还是能通过特定手段获取用户的输入。
附:方法二源代码

运行结果:
运行结果

  • 11
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 要在Qt中显示XML文件,我们可以使用Qt的XML模块和UI界面来实现。 首先,我们需要通过Qt的QFile类读取XML文件。可以使用QFile::open()方法打开XML文件,然后使用QDomDocument类来解析XML数据。QDomDocument类提供了一些方法来访问和操作XML节点。可以使用QDomDocument::setContent()方法将XML内容加载到QDomDocument对象中。 接下来,我们可以使用QDomElement类遍历和访问XML节点。使用QDomDocument::documentElement()方法获取XML文档的根元素,然后使用QDomNodeList类中的方法获取和迭代子元素。 为了在Qt的UI界面中显示XML数据,我们可以使用QtQTreeWidget或QTableWidget进行显示。可以将XML文件的元素和属性作为树形结构或表格的行和列添加到QTreeWidget或QTableWidget中。可以使用QTreeWidgetItem或QTableWidgetItem类创建和设置每个节点的属性和数据。 最后,我们可以将QTreeWidget或QTableWidget添加到Qt窗口或对话框中,或者创建一个新的窗口来显示XML文件。 使用Qt显示XML文件的示例代码如下: ```cpp #include <QDomDocument> #include <QFile> #include <QTreeWidget> #include <QTreeWidgetItem> #include <QVBoxLayout> #include <QMainWindow> void displayXmlFile(const QString& filePath) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) return; QDomDocument xmlDoc; if (!xmlDoc.setContent(&file)) { file.close(); return; } file.close(); QDomElement root = xmlDoc.documentElement(); QTreeWidget* treeWidget = new QTreeWidget(); treeWidget->setColumnCount(2); treeWidget->setHeaderLabels(QStringList() << "Element" << "Value"); displayXmlNode(root, treeWidget); QMainWindow mainWindow; QVBoxLayout* layout = new QVBoxLayout(mainWindow.centralWidget()); layout->addWidget(treeWidget); mainWindow.show(); } void displayXmlNode(const QDomNode& node, QTreeWidget* treeWidget) { if (node.isElement()) { QDomElement element = node.toElement(); QTreeWidgetItem* item = new QTreeWidgetItem(treeWidget); item->setText(0, element.tagName()); QDomNamedNodeMap attributes = element.attributes(); for (int i = 0; i < attributes.count(); ++i) { QDomAttr attribute = attributes.item(i).toAttr(); QTreeWidgetItem* childItem = new QTreeWidgetItem(item); childItem->setText(0, attribute.name()); childItem->setText(1, attribute.value()); } displayXmlNode(node.firstChild(), item); } else if (node.isText()) { QTreeWidgetItem* item = new QTreeWidgetItem(treeWidget); item->setText(1, node.nodeValue()); } displayXmlNode(node.nextSibling(), treeWidget); } ``` 这个示例代码会打开指定的XML文件,并在一个新的窗口中以树形结构展示XML文件的元素和属性。 希望对你有帮助! ### 回答2: QT是一种跨平台的应用程序开发框架,在开发过程中可以使用其提供的XML模块来显示XML文件。首先,需要使用QT提供的QXmlStreamReader类来读取XML文件内容。然后,可以使用QT提供的QTreeView类来显示XML文件的结构。 在代码中,首先需要创建一个QXmlStreamReader对象,然后使用该对象的构造函数将XML文件路径作为参数传入。接着,可以使用while循环来遍历整个XML文件,使用QXmlStreamReader对象的readNext()方法逐个读取XML文件中的元素。 在读取XML元素时,可以使用QTreeView来显示XML文件的结构。可以创建一个QStandardItemModel对象,通过QStandardItemModel的appendRow()方法来逐个添加XML元素。同时,可以利用QTreeView的setModel()方法将QStandardItemModel设置QTreeView的模型,从而显示XML文件的结构。 在循环中,可以使用QXmlStreamReader的nodeType()方法判断当前节点的类型,如果是StartElement类型,说明遇到了一个XML元素的开始标签,可以使用QTreeView的invisibleRootItem()方法返回根节点,然后利用根节点的appendRow()方法添加子节点。如果是EndElement类型,说明遇到了XML元素的结束标签,可以结束当前节点的添加。 最后,可以创建一个QMainWindow对象,并在其中添加一个QTreeView组件,将其居中添加到窗口。最后,在函数中创建一个QApplication对象并执行exec()方法,运行整个程序。 使用以上方法,我们可以成功地在QT中显示XML文件的内容和结构。要注意的是,为了让程序能够正确运行,需要在项目的.pro文件中添加QT += xml 配置项,以引入QT的XML模块。 ### 回答3: 你可以使用Qt框架提供的QXmlStreamReader和QXmlStreamWriter类来显示XML文件。 首先,你需要在项目文件中包含QtCore和QtXml模块。然后,使用QXmlStreamReader类读取XML文件。你可以使用QFile类打开XML文件,并将其传递给QXmlStreamReader构造函数。通过调用readNext()函数,你可以逐个读取XML节点。例如,可以使用name()函数获取当前节点名称,text()函数获取节点文本,和attributes()函数获取节点属性等。你可以根据需要设置循环来读取整个XML文件。 然后,你可以使用Qt的UI组件来显示XML数据。可以创建一个QTextEdit或QPlainTextEdit控件来显示XML内容。你可以使用insertPlainText()或setText()函数将读取到的XML数据插入到文本编辑器中。 在需要显示XML结构的情况下,你可以使用QTreeWidget或QTreeView控件。可以创建一个QTreeWidget,并以递归的方式将XML节点添加为树的子项。可以使用setText()函数设置节点的文本。如果节点具有属性,可以使用addTopLevelItem()函数将属性添加为子项的属性。 最后,你需要将创建的窗口或对话框显示出来,并将读取到的XML数据显示在窗口中。 总结起来,Qt提供了丰富的类和组件来显示XML文件。你可以使用QXmlStreamReader读取XML文件,然后使用适当的Qt UI组件来显示读取到的XML数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值