QWebEngine 初探 显示并跳转页面(QWebEngineView 二级页面 关闭程序时报错)

3 篇文章 0 订阅

目录

1、前言

2、环境

3、实现

3.1 准备

3.2 显示页面

3.2 显示页面并根据点击跳转

4. 关闭程序时是崩溃


1、前言

今天尝试使用Qt的WebEngine模块来在窗口中显示一个网页并跳转链接,着这个过程中遇到一些坑,写在这里吧~

如果只是碰到关闭时报错的问题,请跳到文章 4. 节

2、环境

系统:ubuntu 16.04

Qt版本:5.14.2

IDE:QtCreator (需要安装 QWebEngine 模块)

编译模式:Debug

3、实现

3.1 准备

1. 创建一个Qt Widget Appliciation 项目

2. 在pro文件中:在 QT  += core gui widgets  添加 webenginewidgets 添加之后 QT  += core gui widgets webenginewidgets

3.2 显示页面

在Qt中显示一个网页很容易,只需要在 MainWindow中,创建一个 QWebEngineView 即可,代码如下

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWebEngineView>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QWebEngineView *view = new QWebEngineView(this);
    view->load(QUrl("https:www.baidu.com")); // 设置目标网页
    this->setCentralWidget(view); // 设置为中心窗口
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "webbrowser.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    WebBrowser* web;
};
#endif // MAINWINDOW_H

编译运行即可,效果如图:

此时点击图中的一些需要在新窗口显示的链接是没有作用的,我们往下走,

在新窗口显示的连接指的是点击后会跳转到一个新窗口中显示,就像我们在浏览器中点击这个连接会新建一个标签一样;对于有些网页中的有些按钮是直接在当前页跳转,这种按钮点击是有效的。

3.2 显示页面并根据点击跳转

Qt 已经帮我们在 QWebEngineView 中预留创建窗口的接口 QWebEngineView * createWindow(QWebEnginePage::WebWindowType type); 所以需要我们从 QWebEngineView 派生自己的类并重写该函数;通过这个函数我们决定如何创建新的窗口,注意在创建的时候指定 父类指针!!! 这里我创建了一个名为 WebBrowser的类,代码如下:

头文件 webbrowser.h

#ifndef WEBBROWSER_H
#define WEBBROWSER_H
#pragma once
#include <QWebEngineView>

class WebBrowser : public QWebEngineView
{
    Q_OBJECT
public:
    explicit WebBrowser(QWidget* parent = nullptr);
    ~WebBrowser();
protected:
    QWebEngineView * createWindow(QWebEnginePage::WebWindowType type) override;

private slots:
    void OnUrlChanged(QUrl url); // 测试 urlChanged信号,该信号由 load(QUrl) 触发

};

#endif // WEBBROWSER_H

cpp文件 webbrowser.cpp     注意:在代码中位置指定父指针,如果你这里不像我一样创建一个窗口,则 QWebEngineView 对象必须指定父类指针

#include "webbrowser.h"

#include <QMainWindow>
#include <QDebug>
#include <QWebEngineSettings>
#include <QWebEngineProfile>

WebBrowser::WebBrowser(QWidget* parent):QWebEngineView(parent)
{
    connect(this,&QWebEngineView::urlChanged,this,&WebBrowser::OnUrlChanged);
}
WebBrowser::~WebBrowser(){
}
QWebEngineView * WebBrowser::createWindow(QWebEnginePage::WebWindowType type){
   Q_UNUSED(type)

    QWebEngineView *webbrowser = new QWebEngineView();

    connect(webbrowser,&QWebEngineView::urlChanged,this,&WebBrowser::OnUrlChanged);
    QMainWindow *dialog = new QMainWindow(window()); // 指定父窗口指针!!!
    dialog->setWindowTitle("SubWindow");
    dialog->setCentralWidget(webbrowser);
    dialog->show();

    return webbrowser;
}

void WebBrowser::OnUrlChanged(QUrl url){
    qDebug()<<"url changed "<<url;
}

mainwindow.cpp 

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWebEngineView>
#include "webbrowser.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    auto widget = new WebBrowser();
    widget->load(QUrl("https://www.baidu.com"));
    this->setCentralWidget(widget);
}

MainWindow::~MainWindow()
{
    delete ui;
}

编译运行效果如图,我们在显示出页面之后点击 新闻 会触发新窗口请求,更精细的控制请查阅 QWebEnginePage::WebWindowType 

4. 关闭程序时是崩溃

在我实现代码的时候碰到了这样的问题: 我可以在点击后跳转到新的窗口,但是在我关闭所有窗口的时候报错,如图

原因:我们在createWindow函数中创建新窗口时没有指定父窗口指针,此时的代码是这样的:

QWebEngineView * WebBrowser::createWindow(QWebEnginePage::WebWindowType type){
   Q_UNUSED(type)

    QWebEngineView *webbrowser = new QWebEngineView();

    connect(webbrowser,&QWebEngineView::urlChanged,this,&WebBrowser::OnUrlChanged);
    QMainWindow *dialog = new QMainWindow(); // 没有指定父窗口指针
    dialog->setWindowTitle("SubWindow");
    dialog->setCentralWidget(webbrowser);
    dialog->show();

    return webbrowser;
}

猜测(如果你能解答一定要告诉我!!!非常感谢!!!):应该是和Qt的对象树管理有关系,在我们不指定父窗口的时候,这个对象会被分配到两个对象树当中,这样关闭的时候就会出问题,而在指定父对象之后同属一个对象树;

我的经历:碰到问题后,网上没能查到想要的资料,所以我尝试看了一下源代码,在createWindow 之后会调用 QWebEngineView::load()函数,该函数会跳转到 WebContentsAdapter::load 函数,感觉应该是这个函数中的一些操作造成的,但还需要在研究,还有别的事情,先到者吧

如果你知道准确答案,烦请告诉我!!!!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在C# Web开发中,创建登录页面是一个常见的任务。你可以使用ASP.NET框架来实现这个功能。首先,你需要创建一个ASP.NET Web应用程序项目。在项目中,你可以使用ASP.NET的身份验证和授权功能来处理用户登录。 在项目中,你可以创建一个登录页面的视图(View),通常是一个.cshtml文件。你可以使用HTML和Razor语法来设计和布局登录页面的UI。在登录页面中,你可以添加用户名和密码的输入框,并使用表单(Form)来提交用户的登录信息。 在后端代码中,你可以创建一个控制器(Controller)来处理登录页面的逻辑。在控制器中,你可以编写一个动作方法(Action Method),用于接收用户提交的登录表单数据。在这个方法中,你可以验证用户输入的用户名和密码是否正确,并根据验证结果来决定用户是否成功登录。 为了实现用户登录的持久性,你可以使用ASP.NET的身份验证和授权功能。你可以在用户成功登录后,将用户的身份信息存储在会话(Session)中,或者使用ASP.NET提供的身份验证机制来生成和管理用户的身份凭证。 总结来说,要创建一个C# Web开发的登录页面,你需要: 1. 创建一个ASP.NET Web应用程序项目。 2. 在项目中创建一个登录页面的视图,设计和布局登录页面的UI。 3. 在后端代码中创建一个控制器,编写一个动作方法来处理登录表单的提交。 4. 在动作方法中验证用户输入的用户名和密码,并根据验证结果来决定用户是否成功登录。 5. 可选地,使用ASP.NET的身份验证和授权功能来实现用户登录的持久性。 希望这个回答对你有帮助! #### 引用[.reference_title] - *1* [我的 Java/C# web 后端开发技术选择](https://blog.csdn.net/jacklondon/article/details/124825716)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [C#开发--ASP.NETweb开发初探](https://blog.csdn.net/qq_44964202/article/details/122213441)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值