Qt之QUrl

详细描述

最常见的使用QUrl 的方式是通过构造函数来初始化,传递一个 QString 参数。

QUrl url("https://github.com/");
 
  • 1

然而,也可以使用 setUrl()。

QUrl url;
url.setUrl("https://github.com/");
 
  • 1
  • 2

也可以逐渐地构造 URL,通过调用 setScheme()、setUserName()、setPassword()、setHost()、setPort()、setPath()、setQuery() 和 setFragment()。一些方便的函数也可供使用:setAuthority() 设置用户名、密码、主机和端口。setUserInfo() 设置用户名和密码。

URLs 可以用两种形式表示:编码或未编码。未编码形式适用于显示给用户,编码形式通常会发送到一个 Web 服务器。例如,未编码的URL "http://bühler.example.com/List of applicants.xml" 将被发送到服务器为 "http://xn--bhler-kva.example.com/List%20of%20applicants.xml"

可以使用 toString() 来获取 URL 人类可读的表示。这种表示方法适合以未编码形式将 URL 显示给用户。然而,编码的形式由 toEncoded() 返回,仅供内部使用,传递给 Web 服务器、邮件客户等。两种形式在技术上正确、明确地表示相同的 URL - 事实上,传递任何一种形式给 QUrl 的构造函数或使用 setUrl() 都将产生相同的 QUrl 对象。

QUrl 符合 RFC 3986 (统一资源标识符:通用的语法)中的 URL 规范,包括 RFC 1738 (统一资源定位器)中方案的扩展。如果 QUrl 中的折叠规则符合 RFC 3491 ,它还兼容 file URI specification 来自 freedesktop.org,提供使用 UTF-8(IDN 要求) 本地编码编码的文件名。

RFC 3491 是“Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)”,描述了如何准备一个国际化域名,包括对一个域名字段进行映射、正规化以及禁止性过滤等等操作。

错误检查

在 URL 解析或使用单独的 setter 函数(例如:setScheme()、setHost() 或 setPath())设置 URL 的组成部分时,QUrl 能够检测许多错误。如果解析或 setter 函数成功,任何先前记录的错误条件将被丢弃。

默认情况下, QUrl 的 setter 函数操作在 QUrl::TolerantMode 解析模式下,这意味着他们接受一些常见错误和不实数据。解析的另一种方式是 QUrl::StrictMode,这适用于进一步检查。详见 QUrl::ParsingMode 描述不同的解析模式。

QUrl 只检查符合规范的 URL。它并不试图验证被处理程序预期的高层协议的 URLs 格式。例如,下面的 URIs 都被 QUrl 认为是有效,即使在使用时他们不合理:

  • "http:/filename.html"
  • "mailto://example.com"

当解析器遇到错误时,它通过信号事件 isValid() 返回 false,并且 toString() / toEncoded() 返回一个空字符串。如果需要将 URL 未能解析的原因显示给用户,可以通过调用 QUrl 的 errorString() 来获得错误条件。注意:这个信息是高度技术性的,可能对于用户没有意义。

QUrl 仅能够记录一个错误条件。如果找到一个以上错误,没有定义报告哪个错误。

字符转换

遵循这些原则,以避免在处理 URL 和字符串时,出现错误的字符转换:

  • 当从一个 QByteArray 或一个char * 创建包含 URL 的 QString 时,记得要用 QString::fromUtf8()。

URL格式

scheme

scheme 指定使用的传输协议,它由 URL 起始部分的一个或多个 ASCII 字符表示。scheme 只能包含 ASCII 字符,对输入不做转换或解码,必须以 ASCII 字母开始。

scheme 严格兼容 RFC 3986:scheme = ALPHA *( ALPHA / DIGIT / “+” / “-” / “.” )

协议 描述
file 资源是本地计算机上的文件。格式:file:///,注意后边应是三个斜杠。
ftp 通过 FTP 访问资源。格式:FTP://
gopher 通过 Gopher 协议访问该资源。
http 通过 HTTP 访问该资源。格式:HTTP://
https 通过安全的 HTTPS 访问该资源。格式:HTTPS://
mailto 资源为电子邮件地址,通过 SMTP 访问。格式:mailto:
MMS 通过支持MMS(流媒体)协议的播放该资源(代表软件:Windows Media Player)。格式:MMS://
ed2k 通过 支持ed2k(专用下载链接)协议的P2P软件访问该资源(代表软件:电驴)。格式:ed2k://
Flashget 通过 支持Flashget:(专用下载链接)协议的P2P软件访问该资源(代表软件:快车)。格式: Flashget://
thunder 通过 支持thunder(专用下载链接)协议的 P2P 软件访问该资源(代表软件:迅雷)。格式: thunder://
news 通过 NNTP 访问该资源。

下图显示了一个 URL,其 scheme 是 ftp


要设置 scheme,使用以下方式:

QUrl url;
url.setScheme("ftp");
 
  • 1
  • 2

Authority

URL 的 authority 由用户信息、主机名和端口组成。所有这些元素都是可选的,即使 authority 为空,也是有效的。

格式:username:password@hostname:port

用户信息和主机由'@' 分割,主机和端口由 ':'分割 。如果用户信息为空,'@' 必须被省略。尽管端口为空时,允许使用 ':'


host:指存放资源的服务器的域名系统(DNS)主机名或 IP 地址。

port:整数,可选,省略时使用方案的默认端口,各种传输协议都有默认的端口号,如 HTTP 的默认端口为80。如果输入时省略,则使用默认端口号。有时候出于安全或其他考虑,可以在服务器上对端口进行重定义,即采用非标准端口号,此时,URL 中就不能省略端口号这一项。

user info

user info 指用户信息,是 URL 中 authority 可选的一部分。

用户信息包括:用户名和一个可选的密码,由 ':' 分割。 如果密码为空,':'必须被省略。


path

由零或多个 / 隔开的字符串,一般用来表示主机上的一个目录或文件地址。在 authority 之后,query 之前。


对于没有层级的 schemes,路径将是 scheme 后的所有部分,像下面这样:


相对路径

调用 isRelative() 可以判断 URL 是否是相对的。一个相对的 URL 可以被转变通过将它作为参数传递给 resolved(),会返回一个绝对 URL。isParentOf() 用来确定一个 URL 是否是另一个的 parent。

QUrl resolved(const QUrl &relative) const

如果 relative 不是一个相对 URL,该函数会直接返回 relative。否则,这两个 URL 的路径会进行合并,返回的新 URL 会有 base URL 的 scheme 和 authority。

合并后的路径,就像下面这样:

QUrl baseUrl("http://qt.digia.com/Support/");
QUrl relativeUrl("../Product/Library/");
qDebug(baseUrl.resolved(relativeUrl).toString());
// 打印 "http://qt.digia.com/Product/Library/"
 
  • 1
  • 2
  • 3
  • 4

调用 resolved() 使用 "..",返回原始目录的上级目录。同样,使用 "../.." 将返回上上一层目录。如果 relative 是 "/",路径会变成 "/"

用户输入

[static] QUrl fromUserInput(const QString &userInput)

可以被扣除,返回一个 userInput 指定的有效 URL;如果不能,则会返回一个空 QURL。

大多数应用程序,可以浏览网页,允许用户输入一个 URL 形式的简单字符串。此字符串可以手动输入到地址栏,从剪贴板中获得,或者通过命令行参数传递。

当没有一个有效的 URL 字符串时,执行最好的猜测,使各种web相关的假设。

当字符串对应系统上的一个有效文件路径时,会构造一个 file:// URL,使用 QUrl::fromLocalFile()。

如果不是这种情况,试图把字符串变成一个 http:// 或 ftp:// URL。这时,后者字符串从以 'ftp' 开始。结果然后通过 QUrl 的 tolerant 解析器传递,如果成功,则会返回一个有效的 QUrl;否则,返回 QUrl()。

例如:

  • qt-project.org -> http://qt-project.org
  • ftp.qt-project.org -> ftp://ftp.qt-project.org
  • hostname -> http://hostname
  • /home/user/test.html -> file:///home/user/test.html

文件名

QString fileName(ComponentFormattingOptions options = FullyDecoded) const

返回文件的名称,包括目录路径。

注意:如果这个 QUrl 对象路径以斜杠结束,文件的名称是空的。

如果路径不包含任何斜线,完全返回作为文件名。

示例:

QUrl url("http://qt-project.org/support/file.html");
// url.adjusted(RemoveFilename) == "http://qt-project.org/support/"
// url.fileName() == "file.html"
 
  • 1
  • 2
  • 3

参数 options 控制如何格式化文件名称组成。所有值产生一个明确的结果。使用 QUrl::FullyDecoded,所有百分比编码序列被解码;否则,返回值可能包含在QString的编码形式不能表示的一些百分比编码序列。

主机、端口

例如,通过 socket 连接到一个指定 QUrl 包含的主机、端口:

QTcpSocket sock;
sock.connectToHost(url.host(), url.port(80));
 
  • 1
  • 2

本地文件

可以使用 fromLocalFile() 构造一个 QUrl,通过传递一个本地文件路径。toLocalFile() 将一个 URL 转换为本地文件路径。

QUrl url = QUrl::fromLocalFile("E:\\Qt.txt");
// QUrl("file:///E:/Qt.txt")
 
  • 1
  • 2

百分比编码

为方便生成编码 URL 字符串或查询字符串,有两个静态函数:fromPercentEncoding() 和 toPercentEncoding(),处理编码和解码的百分比 QString 对象。

[static] QByteArray toPercentEncoding(const QString &input, const QByteArray &exclude = QByteArray(), const QByteArray &include = QByteArray())

返回一个编码的输入副本 。输入首先转换为 UTF-8,没有在无限制组中的所有 ASCII 字符是百分比编码的。 为了防止字符变为百分比编码,可以将他们传递给 exclude,为了迫使字符变为百分比编码,将他们传递给 include。

无限制的定义是:ALPHA / DIGIT / “-” / “.” / “_” / “~”

QByteArray ba = QUrl::toPercentEncoding("{a fishy string?}", "{}", "s");
qDebug(ba.constData());
// 打印 "{a fi%73hy %73tring%3F}"
 
  • 1
  • 2
  • 3

有效性

构建一个 URL 后,可以在任何时候调用 isValid(),来检查 URL 的有效性。如果返回 false,应该在继续之前 clear() URL,或通过为 setUrl() 传递一个新的 URL 重新开始。

bool isValid() const

URL 运行通过一致性测试。URL 的每一部分都必须符合 URI 标准的标准编码规则,URL 才是有效的。

bool checkUrl(const QUrl &url) {
    if (!url.isValid()) {
        qDebug(QString("Invalid URL: %1").arg(url.toString()));
        return false;
    }

    return true;
}



<think>好的,用户想了解QtQUrl类的使用方法和示例代码。首先,我需要回忆一下QUrl的基本功能和相关方法。QUrl主要用于处理URL的解析、构造和操作,这在网络编程中非常常见,比如处理HTTP请求、文件路径等。 接下来,我需要确保回答结构清晰,分步骤说明。首先应该介绍QUrl的基本概念,然后逐步展示如何创建QUrl对象、解析URL各部分、修改URL参数、处理编码问题,最后给出一个综合示例。同时,根据用户提供的引用,虽然引用的内容不直接相关,但需要注意引用标识的添加,但看起来用户提供的引用可能没有直接关联,所以可能需要忽略这些引用,除非有相关内容。 用户可能需要看到具体的代码示例,所以每个步骤都应该有对应的代码片段。需要检查代码是否符合Qt的语法,比如是否正确使用QUrl的方法,比如setUrl、scheme、host等。同时,注意代码的格式,使用正确的代码块标记,并确保LaTeX格式的正确应用,比如行内公式用$...$,独立公式用$$...$$,但在这个问题中可能涉及较少数学公式,但如果有涉及URL编码或类似的内容,可能需要用到。 另外,用户要求生成相关问题,需要根据QUrl的常见使用场景和潜在问题来设计。比如如何处理编码、错误处理、与其他Qt网络类的结合使用等。 需要确保回答使用中文,并且结构清晰,分点说明。同时,检查是否有需要添加引用标识的地方,但根据提供的引用内容,可能没有直接相关的,所以可能不需要添加。不过用户示例中有引用标识,所以可能需要确认是否有相关内容可以引用,但根据现有引用内容,可能无法关联,因此可能不需要添加。 最后,综合示例部分需要展示一个实际的应用场景,比如构建一个HTTP请求的URL,并输出各部分信息,这样用户能直观地理解如何使用QUrl。</think>### Qt QUrl 类使用详解 QUrlQt 网络模块中用于处理 URL 解析和构建的核心类,支持标准 URL 格式(如 `http://`、`file://`)和本地文件路径的转换。以下是分步说明及示例代码: --- #### 1. **基本对象创建** ```cpp // 从字符串构造QUrl QUrl url("https://www.example.com:8080/path/to/resource?query=value#fragment"); if (url.isValid()) { qDebug() << "URL有效"; } ``` #### 2. **解析URL组成部分** ```cpp qDebug() << "协议:" << url.scheme(); // 输出: "https" qDebug() << "主机:" << url.host(); // 输出: "www.example.com" qDebug() << "端口:" << url.port(443); // 输出: 8080(若未指定则返回默认值443) qDebug() << "路径:" << url.path(); // 输出: "/path/to/resource" qDebug() << "查询参数:" << url.query(); // 输出: "query=value" qDebug() << "片段标识:" << url.fragment(); // 输出: "fragment" ``` #### 3. **动态构建URL** ```cpp QUrl dynamicUrl; dynamicUrl.setScheme("ftp"); dynamicUrl.setHost("ftp.server.com"); dynamicUrl.setPath("/download/file.zip"); dynamicUrl.setUserName("user"); dynamicUrl.setPassword("pass"); qDebug() << dynamicUrl.toString(); // 输出: "ftp://user:pass@ftp.server.com/download/file.zip" ``` #### 4. **查询参数操作** ```cpp QUrlQuery query; query.addQueryItem("page", "1"); query.addQueryItem("sort", "desc"); url.setQuery(query); qDebug() << url.toString(); // 输出: "https://.../resource?page=1&sort=desc" ``` #### 5. **URL编码与解码** ```cpp // 对特殊字符编码 QString encoded = QUrl::toPercentEncoding("搜索#测试"); qDebug() << encoded; // 输出: "%E6%90%9C%E7%B4%A2%23%E6%B5%8B%E8%AF%95" // 解码 QString decoded = QUrl::fromPercentEncoding(encoded.toUtf8()); qDebug() << decoded; // 输出: "搜索#测试" ``` #### 6. **本地文件路径转换** ```cpp QUrl localFile = QUrl::fromLocalFile("/home/user/文档/report.pdf"); qDebug() << localFile.toString(); // 输出: "file:///home/user/文档/report.pdf" // 反向转换 QString path = localFile.toLocalFile(); ``` --- ### 综合示例:HTTP请求URL构建 ```cpp QUrl httpUrl; httpUrl.setScheme("http"); httpUrl.setHost("api.example.com"); httpUrl.setPath("/v2/data"); QUrlQuery params; params.addQueryItem("category", "technology"); params.addQueryItem("lang", "zh_CN"); httpUrl.setQuery(params); qDebug() << "完整URL:" << httpUrl.toString(); // 输出: "http://api.example.com/v2/data?category=technology&lang=zh_CN" ``` --- ### 常见问题处理 - **有效性检查**:始终通过 `url.isValid()` 验证 URL 合法性,避免解析错误。 - **编码一致性**:处理中文或特殊字符时,显式使用 `toPercentEncoding()` 确保兼容性。 - **端口处理**:使用 `url.port(defaultPort)` 避免未指定端口时返回 `-1`。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值