• ReactiveX 学习笔记(29)使用 RxCpp(RxQt)+ Qt 进行 GUI 编程


    课题

    1. 程序界面由3个文本编辑框和1个文本标签组成。
    2. 要求文本标签实时显示3个文本编辑框所输入的数字之和。
    3. 文本编辑框输入的不是合法数字时,将其值视为0。
    4. 3个文本编辑框的初值分别为1,2,3。

    下载 RxCpp 和 RxQt

    $ git clone --recursive https://github.com/ReactiveX/RxCpp.git
    $ git clone --recursive https://github.com/tetsurom/rxqt.git
    

    创建工程

    启动 Qt Creator, File / New File or Project...
    在向导的第1页选择 Application 分类下的 Qt Widgets Application
    在向导的第2页输入工程名称 RxExample 以及工程所在位置
    在向导的第3页选择 Desktop Qt
    完成向导后点击 Done 创建工程。

    配置工程

    打开工程文件 RxExample.pro,做如下修改

    1. 使用 C++17,即改变 CONFIG 这一项,将 C++11 改为 C++17。
    2. 添加对 RxCpp 和 RxQt 所在路径的引用,即添加 INCLUDEPATH 这一项
    CONFIG += c++17
    INCLUDEPATH += <下载位置>/RxCpp/Rx/v2/src 
        <下载位置>/rxqt/include
    

    配置 UI

    打开 mainwindow.ui,在设计器中做如下修改

    1. 添加 Form Layout。这一步是为了方便添加并定位其他控件。
    2. 在 Form Layout 内添加三个 LineEdit 控件,分别命名为 edtNumber1,edtNumber2,edtNumber3 (设置 objectName 属性)
      然后将其水平对齐属性均改为右对齐(将 alignment/Horizontal 属性设置为 AlignRight )
      然后再将其初值分别设为1,2,3(设置 text 属性)
    3. 在 Form Layout 内添加一个 Label 控件, 将其命名为 lblResult(设置 objectName 属性)
      然后将其水平对齐属性改为右对齐(将 alignment/Horizontal 属性设置为 AlignRight )

    不使用 RxCpp(RxQt) 的解决方案

    打开 mainwindow.ui,在设计器中给三个 LineEdit 控件分别添加 textChanged 事件
    (右键点击控件,然后选择 Go to slot...,然后选择 QLineEdit/textChanged(QString),最后按 OK )
    这一步的结果是在 MainWindow 类中生成(由 IDE 添加)了以下三个方法

    // mainwindow.h
    void on_edtNumber1_textChanged(const QString &arg1);
    void on_edtNumber2_textChanged(const QString &arg1);
    void on_edtNumber3_textChanged(const QString &arg1);
    // mainwindow.cpp
    void MainWindow::on_edtNumber1_textChanged(const QString &arg1)
    {
    }
    void MainWindow::on_edtNumber2_textChanged(const QString &arg1)
    {
    }
    void MainWindow::on_edtNumber3_textChanged(const QString &arg1)
    {
    }
    

    打开 mainwindow.h 和 mainwindow.cpp 在 MainWindow 类中添加 add 方法,执行加法操作

    // mainwindow.h
    void add();
    // mainwindow.cpp
    void MainWindow::add()
    {
        int n = ui->edtNumber1->text().toInt() + ui->edtNumber2->text().toInt() + ui->edtNumber3->text().toInt();
        ui->lblResult->setNum(n);
    }
    

    最后在窗口的构造器以及三个 LineEdit 控件的事件中添加对 add 方法的调用

    // mainwindow.cpp
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        add();
    }
    void MainWindow::on_edtNumber1_textChanged(const QString &arg1)
    {
        add();
    }
    void MainWindow::on_edtNumber2_textChanged(const QString &arg1)
    {
        add();
    }
    void MainWindow::on_edtNumber3_textChanged(const QString &arg1)
    {
        add();
    }
    

    使用 RxCpp(RxQt) 的解决方案

    打开 mainwindow.cpp,添加对 RxQt 的引用并在窗口的构造器中添加事件处理程序,即将文件改为

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <rxqt.hpp> // 添加这一行
    
    // mainwindow.cpp
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        // 执行加法操作
        auto f = [](const QLineEdit* edt) {
            return rxqt::from_signal(edt, &QLineEdit::textChanged)
                .start_with(edt->text());
        };
        f(ui->edtNumber1).combine_latest([](const QString& s1, const QString& s2, const QString& s3){
            return s1.toInt() + s2.toInt() + s3.toInt();
        }, f(ui->edtNumber2), f(ui->edtNumber3))
        .subscribe([&](int n){ui->lblResult->setNum(n);});
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
  • 相关阅读:
    POJ2777
    链表
    模板
    poj 3468(线段树)
    用react编写一个hello world
    用express快速写一个hello world
    naturalWidth与naturalHeight
    div里面的图片垂直居中
    js将网址转为二维码并下载图片
    记一个视频播放器插件 video.js
  • 原文地址:https://www.cnblogs.com/zwvista/p/11039365.html
Copyright © 2020-2023  润新知