范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Qt使用QWebChannel与QWebEngineView内嵌Html交互

  Qt通过QWebEngineView渲染html页面,可以通过QWebChannel结合javascript与html交互
  其中需要2个js文件,一个jquery文件,如果javascript学得好可以不要,一个是qt提供的qwebchannel.js
  先看效果图
  根据qtmarkdown示例做的, 列表使用了自定义类Student,本来想通过自定义QType做交互,但没实现,获取到的数据为null,后该为了QJsonObject,
  首先学生类,其实就是一个简单的c++类#ifndef STUDENT_H #define STUDENT_H #include  #include   // Creating a Custom Type // Before we begin, we need to ensure that the custom type we are creating meets all the requirements imposed by QMetaType. In other words, it must provide: // a public default constructor, // a public copy constructor, and // a public destructor. // 使用Q_PROPERTY 还需要提供一个!=重载以及一个赋值=重载  // The class in Qt responsible for custom types is QMetaType. // To make the type known to this class, we invoke the Q_DECLARE_METATYPE() macro // on the class in the header file where it is defined: // Q_DECLARE_METATYPE(Student);  // To enable creation of objects at run-time, // call the qRegisterMetaType() template function to register // it with the meta-object system. // qRegisterMetaType("Student");  class Student { public:     Student() = default; // 默认构造函数     Student(const QString& name, int age, const QString& tel);     ~Student() = default; // 默认析构函数     Student(const Student&); // 拷贝构造函数      Student& operator=(const Student&); // 赋值重载     bool operator!=(const Student&);     QString getName() const;     int getAge() const;     QString getTel() const;   private:     QString m_Name;     int m_Age;     QString m_Tel; };  Q_DECLARE_METATYPE(Student);  #endif // STUDENT_H
  实现#include "student.h"  Student::Student(const QString &name, int age, const QString &tel)     : m_Name(name)     , m_Age(age)     , m_Tel(tel) {  }  Student::Student(const Student& lt) {     this->m_Name = lt.m_Name;     this->m_Age = lt.m_Age;     this->m_Tel = lt.m_Tel; }  Student& Student::operator=(const Student& lt) {     if (this != <)     {         this->m_Name = lt.m_Name;         this->m_Age = lt.m_Age;         this->m_Tel = lt.m_Tel;     }     return *this; }  bool Student::operator!=(const Student& lt) {     // 只比较name     if (m_Name == lt.m_Name) {         return false;     }     return true; }   QString Student::getName() const {     return m_Name; }  int Student::getAge() const {     return m_Age; }  QString Student::getTel() const {     return m_Tel; }
  最重要的是通信类, 这里有点绕,需要理解信号与槽#ifndef USERDOCUMENT_H #define USERDOCUMENT_H  #include  #include  #include  #include "student.h"   class UserDocument : public QObject {     Q_OBJECT     Q_PROPERTY(QString title MEMBER m_title NOTIFY titleChangedFromQt FINAL)     Q_PROPERTY(QJsonObject jsonStudent MEMBER m_jsonStudent NOTIFY studentChangedFromQt FINAL)  public:     UserDocument(QObject* parent = nullptr) : QObject(parent) {}      // 设置标题并发送titleChangedFromQt     void setTitle(const QString& title);     // 设置学生类并发送studentChangedFromQt     void setStudent(const Student& student);     Student getStudent() const;  signals:     // qt端发送信号给web端同步修改标题     void titleChangedFromQt(const QString& title);     // qt端发送信号给web端同修改学生     void studentChangedFromQt(const QJsonObject& jsonStudent);      // 当web端发送titleChangeFromWeb后同步修改qt端标题     void titleChangedForQt(const QString& title);     // 当web端发送studentChangedFromWeb后同步修改qt端学生     void studentChangedForQt(const Student& student);  public slots:     // web端发送给qt端同步修改标题     void titleChangeFromWeb(const QString& title);     // web端发送给qt端同步修改学生     void studentChangedFromWeb(const QJsonObject& jsonStudent);  private:     QString m_title;     Student m_student;     QJsonObject m_jsonStudent;     QRect m_rect; };  #endif // USERDOCUMENT_H
  实现#include "userdocument.h" #include   void UserDocument::setTitle(const QString& title) {     m_title = title;     emit titleChangedFromQt(m_title); }  void UserDocument::setStudent(const Student& student) {     m_student = student;     QJsonObject jsonStudent;     jsonStudent.insert("name", student.getName());     jsonStudent.insert("age", student.getAge());     jsonStudent.insert("tel", student.getTel());     m_jsonStudent = jsonStudent;      emit studentChangedFromQt(jsonStudent); }  Student UserDocument::getStudent() const {     return m_student; }  void UserDocument::titleChangeFromWeb(const QString& title) {     emit titleChangedForQt(title); }  void UserDocument::studentChangedFromWeb(const QJsonObject& jsonStudent) {     m_jsonStudent = jsonStudent;     QString name = jsonStudent.find("name").value().toString();     int age = jsonStudent.find("age").value().toInt();     QString tel = jsonStudent.find("tel").value().toString();      Student stu{name, age, tel};     m_student = stu;     emit studentChangedForQt(m_student); }
  主界面,ui需要提供一个QLineEdit用作标题,一个QTableWidget显示列表,一个QLineEdit表示名称,一个QSpinBox表示年龄, 一个QLineEdit表示电话,一个QWdiget提升为QWebEngineView显示网页,一个QProgressBar显示网页加载进度, 当然,这个看自己需求。#ifndef MAINWINDOW_H #define MAINWINDOW_H  #include  #include  #include "userdocument.h"  QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE  class MainWindow : public QMainWindow {     Q_OBJECT  public:     MainWindow(QWidget *parent = nullptr);     ~MainWindow();      void initBrower(); // 初始化浏览器     void setStudentList(); // 设置qt端学生列表     void setWebStudentList(); // 设置web端学生列表,通过jquery设置   private slots:     void webViewSource(); // 查看web源码     void webViewProgress(int progress); // web加载进度     void webViewLoadFinished(bool finisned); // web加载完毕     void titleChanged(); // qt端标题修改      void titleChangedForQt(const QString& title); // web端标题修改     void studentChangedForQt(const Student& student); // web端学生修改      void selectTableRow(int index); // QTableWidget行选中     void btnSubmitClicked(); // 提交按钮  private:     Ui::MainWindow *ui;      UserDocument m_UserDocument;     QStringList m_studentListHeader;     QList m_studentList; }; #endif // MAINWINDOW_H
  实现#include "mainwindow.h" #include "ui_mainwindow.h" #include  #include  #include  #include "student.h" #include  #include   MainWindow::MainWindow(QWidget *parent)     : QMainWindow(parent)     , ui(new Ui::MainWindow) {     ui->setupUi(this);     ui->pProgressWebLoad->setMaximumHeight(5);     ui->pProgressWebLoad->hide();      // 标题改变,html里面的标题也跟着改变     connect(ui->pLeMainTitle, &QLineEdit::textChanged, this, &MainWindow::titleChanged);     // QTableWidget行点击     connect(ui->pTbUserList->verticalHeader(), &QHeaderView::sectionClicked, this, &MainWindow::selectTableRow);     // 提交按钮     connect(ui->pBtnSubmit, &QPushButton::clicked, this, &MainWindow::btnSubmitClicked);     // 初始化浏览器     initBrower();  }  MainWindow::~MainWindow() {     delete ui; }  void MainWindow::initBrower() {     ui->pWebBrower->load(QUrl("qrc:/resources/index.html"));      QWebChannel* channel = new QWebChannel(this);     // web与qt通信主要手段     channel->registerObject("UserDocument", &m_UserDocument);     ui->pWebBrower->page()->setWebChannel(channel);      // 初始化web标题     m_UserDocument.setTitle("User Manage");     // 模拟部分学生     Student stu = {"Jone", 18, "028-87930392"};     Student stu2 = {"Jim", 17, "028-46443534"};     Student stu3 = {"Sam", 18, "028-57657446"};     Student stu4 = {"Lucy", 17, "028-78745448"};     m_studentList.append(stu);     m_studentList.append(stu2);     m_studentList.append(stu3);     m_studentList.append(stu4);     // 初始化web表单     m_UserDocument.setStudent(stu);     // web端学生修改     connect(&m_UserDocument, &UserDocument::studentChangedForQt, this, &MainWindow::studentChangedForQt);     // web端标题修改     connect(&m_UserDocument, &UserDocument::titleChangedForQt, this, &MainWindow::titleChangedForQt);      // 初始化qt表单     ui->pLeName->setText(stu.getName());     ui->pSbAge->setValue(stu.getAge());     ui->pLeTel->setText(stu.getTel());     // 设置QTableWidget 表头     m_studentListHeader << "Name" << "Age" << "Tel";     ui->pTbUserList->setColumnCount(m_studentListHeader.count()); // 这个要在setHorizontalHeaderLabels前     ui->pTbUserList->setHorizontalHeaderLabels(m_studentListHeader);      // 初始化qt端学生列表     setStudentList();      // 把前进、后退、刷新按钮加入到页面     QToolBar* toolBar = addToolBar("Tool");     toolBar->addAction(ui->pWebBrower->pageAction(QWebEnginePage::Forward));     toolBar->addAction(ui->pWebBrower->pageAction(QWebEnginePage::Back));     toolBar->addAction(ui->pWebBrower->pageAction(QWebEnginePage::Reload));     // 添加查看源码按钮     toolBar->addAction("ViewSource", this, &MainWindow::webViewSource);      // web加载进度     connect(ui->pWebBrower->page(), &QWebEnginePage::loadProgress, this, &MainWindow::webViewProgress);     // web加载完毕     connect(ui->pWebBrower->page(), &QWebEnginePage::loadFinished, this, &MainWindow::webViewLoadFinished); }  void MainWindow::setStudentList() {     ui->pTbUserList->setRowCount(m_studentList.count());      int i = 0;     for (Student stu : m_studentList)     {         QTableWidgetItem* item;         item = new QTableWidgetItem(stu.getName());         ui->pTbUserList->setItem(i, 0, item);         item = new QTableWidgetItem(QString::number(stu.getAge()));         ui->pTbUserList->setItem(i, 1, item);         item = new QTableWidgetItem(stu.getTel());         ui->pTbUserList->setItem(i, 2, item);         i++;     } }  void MainWindow::setWebStudentList() {     QString html(tr("%1%2%3")                  .arg(m_studentListHeader.at(0))                  .arg(m_studentListHeader.at(1))                  .arg(m_studentListHeader.at(2)));      for (Student stu : m_studentList)     {         QString body(tr("%1%2%3")                      .arg(stu.getName())                      .arg(stu.getAge())                      .arg(stu.getTel()));         html += body;     }     // 使用jquery同步学生列表     QString code(tr("$qt.jQuery("#users").html("%1")").arg(html));     // 执行javascript     ui->pWebBrower->page()->runJavaScript(code); }  void MainWindow::webViewSource() {     // 查看源码     QTextEdit* source = new QTextEdit(nullptr);     source->setAttribute(Qt::WA_DeleteOnClose); // 关闭自动delete     ui->pWebBrower->page()->toHtml([source](const QString& html) {         source->setPlainText(html);     });     source->resize(600, 500);     source->show(); }  void MainWindow::webViewProgress(int progress) {     // 当在加载中时显示进度条,否则不显示     if (progress < 100) {         ui->pProgressWebLoad->show();     } else {         ui->pProgressWebLoad->hide();     }     ui->pProgressWebLoad->setValue(progress); }  void MainWindow::webViewLoadFinished(bool finisned) {     if (finisned)     {         // web加载完毕就初始化学生列表         setWebStudentList();     }  }  void MainWindow::titleChanged() {     // qt端标题修改同步修改web端标题     m_UserDocument.setTitle(ui->pLeMainTitle->text()); }  void MainWindow::titleChangedForQt(const QString& title) {     // web端标题修改同步修改qt端标题     ui->pLeMainTitle->setText(title); }  void MainWindow::studentChangedForQt(const Student& student) {     // web端x学生添加同步添加qt端学生,  修改原理一样     ui->pLeName->setText(student.getName());     ui->pSbAge->setValue(student.getAge());     ui->pLeTel->setText(student.getTel());     m_studentList.append(student);     setStudentList();     setWebStudentList(); }  void MainWindow::selectTableRow(int index) {     // QTableWidget行选中     QTableWidgetItem* itemName = ui->pTbUserList->item(index, 0);     QTableWidgetItem* itemAge = ui->pTbUserList->item(index, 1);     QTableWidgetItem* itemTel = ui->pTbUserList->item(index, 2);     QString name = itemName->text();     int age = itemAge->text().toInt();     QString tel = itemTel->text();      // 获取到的数据同步到qt表单     ui->pLeName->setText(name);     ui->pSbAge->setValue(age);     ui->pLeTel->setText(tel);      // 获取到的数据同步到web表单     Student stu = {name, age, tel};     m_UserDocument.setStudent(stu); }  void MainWindow::btnSubmitClicked() {     // 提交表单     QString name = ui->pLeName->text();     int age = ui->pSbAge->value();     QString tel = ui->pLeTel->text();     // 只做添加     Student stu = {name, age, tel};     m_studentList.append(stu);     setStudentList();     setWebStudentList(); }
  html页面比较简单,懂前端的应该不难看懂                       User Manage                                                                            


买华为mate还是p20?这两款华为系列手机都属于华为高端旗舰产品,华为mate系列目前最新的机型为mate10系列。也即将更新mate20,P系列也是属于旗舰机型最新机型为P20!mate10采用5。9英华为mate40已经降到4199了,这也太香了吧华为mate40系列可是华为手机里面最受欢迎的型号之一了吧!搭载华为麒麟9000的处理器,,支持40W的快充,最重要的是全网通5G。以至于此次华为P50系列上市,也丝毫没有影响ma新能源物流车市场觉醒选一块好电池有多重要?新能源物流车经过几年的发展,数量不断增加,目前保有量已超过50万辆。越来越多的运营经销商金融机构终端用户开始接触新能源物流车。当前,部分城市的新能源物流车市场正处于觉醒时分,想加入小米手机官方维修能信吗?我的小米10s摔地上,前屏因为贴了钢化膜所以钢化膜和屏都没有破损,后玻璃盖碎了。前屏磕成漏液,造成手机上半部分不显示触摸屏失灵,没办法关机。只能下半部分打开app然后上滑退出。八月个性DIY,定制属于自己的插排,奥睿科ORICO无线插排插排,无论是家庭还是办公都很常用的设备。想必不用过多介绍,大家都很熟悉。但是平时使用时也会遇到一些问题,大多集中在线缆的问题,要么不够长要么材质差使用中容易过热等问题。正好看到OR更新F13使用体验OPPOA91就在刚刚也是推送了colorOS11F13安卓补丁,在为时一天的使用体验下来分享这次优化的部分。优化系统UI动画从系统底层优化A91的打开退出以及其他多种场景下的动画哪一品牌的电视盒子值得推荐,波多星Y1实测无广告且不卡顿最近有朋友问什么牌子的电视盒子最好,我花了半个月的时间仔细评估了波多星电视盒子Y1,想向大家推荐一下这一款电视盒子。先简单说明一下我为什么推荐这款电视盒子,因为它实在是太方便了,简超长待机还能给手机充电,出门必备神器南卡N2s开箱超长待机还能给手机充电,出门必备神器南卡N2s开箱说起蓝牙耳机,以前可能大家还在纠结到底买国际大品牌还是买国产新兴品牌,而如今蓝牙耳机就和智能手机一样,通过近几年的高速发展,各大品企业办公更畅爽,宝藏品牌爱快WiQ1800评测如今,随着企业数字化转型的进程不断加快,联网终端的数量激增,伴随而来的是企业愈发重视影响其核心业务的网络基础设施和网络设备建设另一方面,随着WiFi6新一代无线局域网传输技术的兴起售价2499起!小米平板5pro速览这是一块11的大屏幕,却拥有2。5K超清晰显示,支持HDR1O,每一处细节都细腻养眼,多达1O亿色的真彩显示,为你真实还原天地间的缤纷多彩。轻盈机身,纤薄设计骁龙870处理器当家旗2021年1000元2000元档最值得买的3款手机超高性价比一红米K40系列1性能。红米K40在2000元价位上采用了次旗舰处理器骁龙870,跑分仅次于骁龙888。足以流畅地运行所有的app,带来畅快的体验。2屏幕。K40采用了三星新一代E
本月五次减持,女股神套现3亿美元,特斯拉何时能冲击万亿市值?特斯拉的神话还在继续,但是有人已经开始率先抛售,这是对特斯拉的不看好?还是只是单纯地获利卖出?作为美股市场上最做不空的股票,过去的数年间特斯拉的暴涨让不少做空的投资机构损失惨重,于当你的股票被套后,下跌超过多少时,你会麻木装死,不再看股票?首先有问题中这种思想就是错误的,炒股必须必须必须设置止损线,否则大部分时间解套只能靠割肉割肉割肉!很多人过来问股,经常用的一句话,就是我短线被套了,可以做中线吗?excuseme?1500元档如何选择一款待机时间长,久玩不卡而且品牌还比较大的手机呢?很高兴能够为您回答问题!当下手机市场竞争十分的激烈,手机的价格也是层出不穷,但是,要想买一部价格便宜而且性能优异的手机也并不是一件难事,接下来就让我为大家盘点一些价格在1500元左曲面屏麒麟芯片,华为5G旗舰少量现货供应,不等iPhone13了?从目前的形式来看,如今的iPhone13系列已经是属于大卖的情况,而此番所提及到的13香也是名不虚传,针对于iPhone13系列能够在国内市场火爆也并不会感到意外,毕竟现如今的iPOPPOReno8概念机1亿像素大眼主摄5500mAh大电池今天给大家介绍的是一款OPPOReno8概念机。这款概念机搭载了高通骁龙888处理器,配备了1。08亿像素大眼主摄,采用了一块120Hz超高刷新率2K屏,内置了5500mAh大电池极客简报华为跌倒苹果吃饱HarmonyOS用户破亿华为先于Win11支持手机应用航天发射再次迎来密集期Pixel6未至,Google薯片先行。iPhone13系列正式发布,下周到手本周苹果召开新品发布会,iPhone13系列iPa华为MateStationX一体机能否与苹果iMac一战?这两没有什么可战的,一个是别家硬件组装的windows机器,芯片和操作系统都是别家的。一个是高度集成的自家IOS。没有战性。如果华为station非要战,对标的竟品也该是DELL和iPhone13首发评测变强了,还更亲民了?拿到iPhone13系列之后,我们第一时间模仿苹果官方短片Whodunnit的风格,也拍了个小片段,旨在体验苹果重点宣传的电影效果模式。不过在深入研究这一功能之前,我们还是先来看看老司机确认,3000块以内,这5款手机基本无敌或许是因为今年的高通芯片在能耗上存在短板,使得今年新发布的手机在价格上明显比去年的骁龙865手机便宜很多。去年大多数骁龙865手机的价格都在三千块以上。图片来源于网络但今年三千块以为什么苹果手机不用安装杀毒软件?正确来说是未越狱的苹果手机不用安装杀毒软件。因为越狱就意味着获取了开发者权限,可以绕过应用商店进行软件的安装,也就是说可以安装自己从网上下载的未知是否安全的应用。这也意味着并不安全微信这限制终于取消,能刷淘宝看抖音了上周,小果给大家分享过一条消息,工信部要求阿里腾讯等解除屏蔽链接。工信部表示,无正当理由来限制网址链接的识别解析和正常访问,严重影响了用户体验,损害了用户权益,扰乱了市场秩序。要求