全流程机器视觉工程开发(一)环境准备,paddledetection和labelme-CSDN博客

mikel阅读(501)

来源: 全流程机器视觉工程开发(一)环境准备,paddledetection和labelme-CSDN博客

前言
我现在在准备做一个全流程的机器视觉的工程,之前做了很多理论相关的工作。大概理解了机器视觉的原理,然后大概了解了一下,我发现现在的库其实已经很发展了,完全不需要用到非常多的理论,只需要知道开发过程就可以了,甚至paddlex已经直接有了傻瓜式模型训练的软件,所以我现在准备来做一个全流程机器视觉工程开发,不涉及过多理论。

准备
现在准备一下机器视觉工程的前情提要。

我准备使用paddledetection来做机器视觉。什么是paddleDetection?你可以理解为paddlepaddle对于目前主流的机器学习模型做了一些整合,只需要使用paddleDetection库就可以做一个很方便的训练、预测等工作。

准备好paddledetection之后,也就是我们的模型工具之后,还需要对现有图片做一些简单的划分工作,这里就需要用到labelme工具来进行.

 

环境安装
我这个教程和别的教程不太一样。因为年代久远,paddledetection库的原始安装方式已经不太适用了,所以我这里重新写一个paddledetection安装方式。

主要流程大概如下:

安装anaconda
安装paddle库
安装CUDA库
去github上下载paddledetection仓库
给自己安装pycocotools和lap库
直接安装paddledetection的依赖包requirements.txt
安装paddledetection
流程
安装anaconda
这步略,不知道的可以浏览:Anaconda安装教程(超详细版)

安装paddle库
这步略,参考paddle官网,不行就自己在csdn上搜,或者看我往期
这里给出官网链接:开始使用

安装CUDA库
这步略,参考本人往期文章:简易机器学习笔记(十)Windows下 PaddlePaddle配置CUDA加速环境

去github上下载paddledetection仓库
github链接:PaddleDetection
你要做的就是直接把这个仓库clone到本地,拉下来的项目大概是这样的

里面是这一大堆东西,暂时先不管是干嘛的,只需要先放在这里就可以了。

pycocotools和lap库
到一般的教程了,这里会告诉你直接去安装requirements.txt,但是很多人现在可能会直接报错numpy的问题,这个可能是因为库实在是年久失修了,主要出问题的库实际上就那么两个,一个是pycocotools,一个是lap
首先可以尝试一下能不能直接安装这两个库,也就是直接尝试以下两条命令

pip install pycocotools
pip install lap

一般情况下这个pycocotools是没问题的,出问题的是这个lap库,我这里主要演示lap库怎么手动安装,pycocotools也是同理

首先我们找到两个库的github地址:

pycocotools
lap

把这两个库clone到本地,大概是这样

在cmd中使用python尝试安装这个setup.py文件,指令大概是:

#path/to/setup.py指代setup.py的路径
python path/to/setup.py install

注意这条指令需要使用setuptools,怎么安装这个库不过多赘述了

一般这样手动安装就可以正常安装成功了,pycocotools和lap库都是这样安装的。

直接安装paddledetection的依赖包requirements.txt
lap库和pycocotools安装完毕后,基本上问题就不大了。现在只需要使用以下指令来对paddledetection包中的requirements进行安装就行了

#path/to/requirements.txt 指代paddledetection库下的requirements.txt的路径
pip install -r path/to/requirements.txt

我们可以打开requirements.txt来看一看,里面也只有一些库的名字而已

 

安装paddledetection
到这里基本上就快安装完了,只需要最后一步,就是安装paddledetection,流程和安装lap库差不多
#path/to/setup.py 指代paddledetection库下的setup.py的路径
python path/to/setup.py install

数据标注工具labelme
刚刚我们安装完了paddledetection库,也就是准备好模型,接下来要准备的就是数据标注工具labelme

这个比较简单,直接参考博客:添加链接描述
————————————————
版权声明:本文为CSDN博主「Leventure_轩先生」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Andius/article/details/135675515

浅谈6种流行的API架构风格 - 追逐时光者 - 博客园

mikel阅读(511)

来源: 浅谈6种流行的API架构风格 – 追逐时光者 – 博客园

浅谈6种流行的API架构风格

前言

API在现代软件开发中扮演着重要的角色,它们是不同应用程序之间的桥梁。编写业务API是日常开发工作中最常见的一部分,选择合适的API框架对项目的成功起到了至关重要的作用。本篇文章将浅谈一下当前6种流行的API架构风格的优点、缺点以及适用场景。

6种流行的API架构风格图

SOAP

SOAP全拼:Simple Object Access Protocol

  • 优点:SOAP 是一种基于 XML 的通信协议,具有良好的跨平台和跨语言支持。它提供了丰富的安全性和事务管理功能,并支持复杂的消息交换模式。
  • 缺点:SOAP 在处理大量数据时可能效率较低,因为它使用了冗长的 XML 格式,并且需要较多的带宽和处理能力。
  • 适用场景:SOAP 适用于需要高安全性和复杂数据交换的企业级应用程序和 Web 服务场景,尤其是需要实现事务处理和消息传递机制的场景。

RESTful

RESTful全拼:Representational State Transfer

  • 优点:RESTful 一种基于现有 Web标准和 HTTP协议的设计和构建网络应用程序的架构风格,旨在提供一种简洁、可扩展、可靠和可互操作的方式来进行网络通信。它具有良好的可伸缩性、可缓存性和可见性,并支持多种数据格式(如:JSON、XML等)。
  • 缺点:缺乏标准化、安全性问题、粒度问题、难以处理复杂逻辑、复杂性问题和版本管理问题。
  • 适用场景:RESTful 适用于构建 Web 应用程序和移动应用程序的 API,特别是那些需要简单和易于使用的场景。

GraphQL

  • 优点:GraphQL 是一种由 Facebook 开发的查询语言和运行时执行环境。它允许客户端精确地指定所需的数据,并减少了网络传输的数据量。GraphQL 还提供了强大的类型系统和自动文档生成。
  • 缺点:GraphQL 在处理大型查询和复杂数据模型时可能存在性能问题,因为它需要在运行时解析查询,并执行多个数据源之间的数据获取操作。
  • 适用场景:GraphQL 适用于需要灵活数据获取和精确控制的应用程序,特别是面向移动设备的应用程序和需要聚合多个数据源的场景。

gRPC

gRPC全拼:Google Remote Procedure Call

  • 优点:gRPC 是一种高性能、开源的远程过程调用框架,基于 Protocol Buffers(protobuf)序列化协议。它提供了强大的类型系统、双向流和流式数据传输的支持。
  • 缺点:gRPC 对网络稳定性有较高的要求,不太适合部署在不可靠的网络环境中。
  • 适用场景:gRPC 适用于构建分布式系统和微服务架构,特别是那些需要高性能和强类型约束的场景。

WebSocket

  • 优点:WebSocket 提供了全双工通信的能力,允许服务器主动向客户端推送数据。它具有低延迟、高吞吐量和实时性的特点。
  • 缺点:WebSocket 对于服务器和客户端都需要保持长时间的连接,这可能增加服务器的负载,并且需要较高的网络稳定性。
  • 适用场景:WebSocket 适用于实时通信和实时数据更新的应用程序,特别是聊天应用、协作工具和实时游戏等场景。

Webhook

  • 优点:Webhook 是一种通过 HTTP 请求将事件通知发送给预定义 URL 的机制。它能够实时推送数据并触发自定义的后续操作。
  • 缺点:Webhook 需要事先配置目标 URL,并且对于每个事件都需要建立一个独立的 Webhook。此外,Webhook 不支持请求-响应模式。
  • 适用场景:Webhook 适用于需要实时事件通知和与其他应用程序集成的场景,特别是信息发布、应用程序集成和自动化工作流等场景。

总结

这些 API 架构风格都各有优点和适用场景,您可以根据具体需求选择适合的架构风格来构建和设计 API。

 

 

解决WordPress”无需升级 您的WordPress数据库已经是最新的了!” 关闭插件后无法登陆后台-腾讯云开发者社区-腾讯云

mikel阅读(493)

来源: 解决WordPress”无需升级 您的WordPress数据库已经是最新的了!” 关闭插件后无法登陆后台-腾讯云开发者社区-腾讯云

捣鼓另一个站点的时候关闭了全部插件,结果前台无法访问,后台提示”无需升级 您的WordPress数据库已经是最新的了!”,如下图。因为这个站点是有使用缓存的,可能是关闭了缓存导致的。

解决办法,前往你的WordPress安装目录下的  wp-content  下。找到object-cache.php,把它的名字改一下(改成任意都可以。)

然后就可以访问了,恢复正常。

宝塔中nginx配置websocket的wss协议_宝塔安装websocket启动-CSDN博客

mikel阅读(750)

来源: 宝塔中nginx配置websocket的wss协议_宝塔安装websocket启动-CSDN博客

配置ws也就是不安全的协议,比较简单,可以参考我之前的文章
在配置wss之前要准备好ssl证书,
配置证书也很简单,只要上传两个证书,就好了,我这里就不再赘述了,我这里证书已经配置好了,配置wss的代码如下
server
{
    listen 80;
listen 443 ssl http2;
    server_name kf.xxx.com;
    index index.php index.html index.htm default.php default.htm default.html;
    root /www/wwwroot/kf.xxx.com/public;
    #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
    #error_page 404/404.html;
    #HTTP_TO_HTTPS_START
    if ($server_port !~ 443){
        rewrite ^(/.*)$ https://$host$1 permanent;
    }
    #HTTP_TO_HTTPS_END
    ssl_certificate    /www/server/panel/vhost/cert/kf.xxx.com/fullchain.pem;
    ssl_certificate_key    /www/server/panel/vhost/cert/kf.xxx.com/privkey.pem;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    error_page 497  https://$host$request_uri;
    #SSL-END
    #ERROR-PAGE-START  错误页配置,可以注释、删除或修改
    #error_page 404 /404.html;
    #error_page 502 /502.html;
    #ERROR-PAGE-END
    #PHP-INFO-START  PHP引用配置,可以注释或修改
    include enable-php-56.conf;
    #PHP-INFO-END
    #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
    include /www/server/panel/vhost/rewrite/kf.xxx.com.conf;
    #REWRITE-END
    #禁止访问的文件或目录
    location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
    {
        return 404;
    }
    #一键申请SSL证书验证目录相关设置
    location ~ \.well-known{
        allow all;
    }
    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    {
        expires      30d;
        error_log off;
        access_log /dev/null;
    }
    location ~ .*\.(js|css)?$
    {
        expires      12h;
        error_log off;
        access_log /dev/null;
    }
    location / {
      if (!-e $request_filename) {
        rewrite ^(.*)$ /index.php?s=$1 last;
        break;
      }
    }
     location /wss {
            proxy_pass http://127.0.0.1:7272;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection “upgrade”;
            rewrite /wss/(.*) /$1 break;
            proxy_redirect off;
  }
    access_log  /www/wwwlogs/kf.xxx.com.log;
    error_log  /www/wwwlogs/kf.xxx.com.error.log;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
其中最重要的就是这一部分
 location /wss {
            proxy_pass http://127.0.0.1:7272;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection “upgrade”;
            rewrite /wss/(.*) /$1 break;
            proxy_redirect off;
  }
1
2
3
4
5
6
7
8
9
10
11
因为我的服务器上已经开了一个7272端口,这个端口运行的是websocket服务,当路径包含/wss就走到这个服务,
所有在调用的时候也得包含/wss,调用的代码如下,我截取了一部分
一定要跟一个/wss不然找不到。
————————————————
版权声明:本文为CSDN博主「reg183」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chendongpu/article/details/123354674

宝塔nginx环境如何配置 wss WebSocket 连接_宝塔如何建立websocket协议的链接-CSDN博客

mikel阅读(650)

来源: 宝塔nginx环境如何配置 wss WebSocket 连接_宝塔如何建立websocket协议的链接-CSDN博客

1、需要一个备案域名,在宝塔可申请免费ssl证书,ssl 证书这里有个大坑,为何宝塔申请成功总是访问https失败,我发现关闭防火墙就行了。

2、开放端口,宝塔环境新开放一个端口

nginx 配置

 

location /wss {
proxy_pass http://127.0.0.1:2022;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
rewrite /wss/(.*) /$1 break;
proxy_redirect off;
}

3、宝塔终端启动:php server.php start -d

4、测试:

<!DOCTYPE html>

<html>

<head>

<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />

<title>Title</title>

</head>

<body>

<script>

var ws = new WebSocket(“wss://www.xxx.com/wss”);

ws.onopen = function() {

alert(“连接成功”);

ws.send(‘tom’);

alert(“给服务端发送一个字符串:tom”);

};

ws.onmessage = function(e) {

alert(“收到服务端的消息:” + e.data);

};

</script>

</body>

</html>
————————————————
版权声明:本文为CSDN博主「神夜大侠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012015434/article/details/124890321

5种设置ASP.NET Core应用程序URL的方法 - 知乎

mikel阅读(722)

来源: 5种设置ASP.NET Core应用程序URL的方法 – 知乎

默认情况下,ASP.NET Core应用程序监听以下URL:

在这篇文章中,我展示了5种不同的方式来更改您的应用程序监听的URL。

  • 在Program.cs中使用 UseUrls()
  • 环境变量 – 使用DOTNET_URLS或者 ASPNETCORE_URLS
  • 命令行参数 – 设置命令行参数--urls
  • launchSettings.json – 设置 applicationUrl 属性
  • KestrelServerOptions.Listen() – 使用 Listen() 手动使用配置Kestrel服务器的地址

我将在下面更详细地介绍每个选项。

UseUrls()

设置绑定URL的第一个也是最简单的方法,在配置IWebHostBuilder的时候使用UseUrls()进行硬编码。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.UseUrls("http://localhost:5003", "https://localhost:5004");
            });
}

环境变量

.NET Core使用两种类型的配置:

  • DOTNET_URLS
  • ASPNETCORE_URLS

如果您同时设置了这两个环境变量,那么ASPNETCORE_URLS参数优先。

您可以用不同的方式设置环境变量。例如,使用命令行:

setx ASPNETCORE_URLS "http://localhost:5001"

使用powershell

$Env: ASPNETCORE_URLS = "http://localhost:5001"

使用bash:

export ASPNETCORE_URLS="http://localhost:5001;https://localhost:5002"

如上所示,您还可以通过使用分号分隔多个地址来传递多个地址以进行监听(使用HTTP或HTTPS)。

命令行参数

设置主机配置值的另一种方法是使用命令行。如果设置了命令行参数,那么会覆盖环境变量的值, 只需使用--urls参数:

dotnet run --urls "http://localhost:5100"

和上面一样,您可以通过使用分号将多个URL分开来设置多个URL:

dotnet run --urls "http://localhost:5100;https://localhost:5101"

环境变量和命令行参数可能是在生产环境中为应用程序设置URL的最常见方法,但是它们对于本地开发来说有点麻烦。通常使用launchSettings.json会更容易。

launchSettings.json

大多数 .NET项目模板在Properties文件夹中都包含launchSettings.json文件,这个文件包含了启动.NET Core应用程序的各种配置文件。

{
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:38327",
      "sslPort": 44310
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "TestApp": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

launchSettings.json还提供了environmentVariables参数,您可以用它来设置环境变量,就像上面这样,然后我们可以选择不同的启动类型:

KestrelServerOptions.Listen

默认情况下,几乎所有的.NET Core应用程序都配置了Kestrel,如果需要,您可以手动配置Kestrel的端点,也可以配置KestrelServerOptions。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.UseKestrel(opts =>
                {
                    // Bind directly to a socket handle or Unix socket
                    // opts.ListenHandle(123554);
                    // opts.ListenUnixSocket("/tmp/kestrel-test.sock");
                    opts.Listen(IPAddress.Loopback, port: 5002);
                    opts.ListenAnyIP(5003);
                    opts.ListenLocalhost(5004, opts => opts.UseHttps());
                    opts.ListenLocalhost(5005, opts => opts.UseHttps());
                });

            });
}

我个人没有以这种方式在Kestrel中设置监听端点,但是很高兴知道可以根据需要完全控制Kestrel。

总结

在这篇文章中,我展示了五种不同的方式来设置应用程序监听的URL。UseUrls()是最简单的一种,但通常不适合在生产中使用, launchSettings.json文件是在开发环境中设置的URL是非常有用的。 在生产中我们通常使用命令行参数–urls或者环境变量ASPNETCORE_URLS和DOTNET_URLS, 希望对您有帮助。

原文链接: https://andrewlock.net/5-ways-to-set-the-urls-for-an-aspnetcore-app/

Chrome(谷歌)浏览器跨域请求被阻止,CORS 头缺少‘Access-Control-Allow-Origin’的解决办法

mikel阅读(1830)

http://aszhi.com/jishu/80.html

使用Chrome(谷歌)浏览器跨域访问不在同一域名下的资源文件(ip地址+端口号)时,会报“No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”错误。因为被请求的资源没有设置‘Access-Control-Allow-Origin’,所以浏览器同源策略限制了此类发起的请求不被允许。

Access to XMLHttpRequest at ‘http://www.quguangjie.cn/home/login/see’ from origin ‘null’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

翻译:因为被请求的资源没有设置‘Access-Control-Allow-Origin’,所以 从’http://www.quguangjie.cn/’发起的请求不被允许。

被请求的资源没有设置‘Access-Control-Allow-Origin’

分析原因

已拦截跨源请求:同源策略禁止读取位于 http://www.quguangjie.cn/home/login/see 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin’)。

Chrome(谷歌)浏览器可以通过设置,解决跨域问题的方法

设置方法:在双核Chrome浏览器(版本3.0.1.6,内核版本75.0.3770.100)的快捷图标上点击 鼠标右键 ——》点击“属性”选择“快捷方式”标签——》“目标”里面,在原chrome路径的基础上增加 –allow-file-access-from-files——》应用——》确定 关闭属性窗口——》关闭所有已打开的chrome,重新启动。

Chrome浏览器通过设置解决跨域问题

PS:增加–allow-file-access-from-files后缀时,一定要有空格,如果不加空格,你会惊奇的发现你无法修改成功。

通过添加“扩展程序”设置Allow CORS

设置方法:打开双核Chrome浏览器(版本3.0.1.6,内核版本75.0.3770.100)点击 自定义及控制 ——》点击“扩展程序”——》获取更多扩展程序——》在搜索框中输入 Access-Control-Allow-Origin,选择对应的“Allow CORS: Access-Control-Allow-Origin”——》安装即可。

PS:“Access-Control-Allow-Origin”是谷歌应用,估计需要翻墙才能下载安装。

扩展程序Allow CORS: Access-Control-Allow-Origin

上述步骤设置完之后如果仍然报错,那就再按照网上大家分享的方法继续处理

第一种方法:被请求页面加上下面的代码,最好content填写域名

  1. < meta http-equiv=”Access-Control-Allow-Origin” content=”*” >

第二种方法:在请求控制器加上加上下面的代码

  1. header(“Access-Control-Allow-Origin: *”);

第三种方法:IIS、Apache、Nginx可以直接配置Access-Control-Allow-Origin 跨域,具体如下:

IIS配置

只需要在IIS添加HTTP响应标头即可!

  1. AccessControlAllowHeadersContentType, api_key, Authorization
  2. AccessControlAllowOrigin:*
Apache配置

主要修改http.conf 或者,修改Apache伪静态规则文件.htaccess

  1. <Directory “/Users/cindy/dev>
  2. AllowOverride ALL
  3. Header set Access-Control-Allow-Origin *
Nginx配置

主要是修改nginx.conf

  1. location ~* .(eot|ttf|woff|svg|otf){
  2. add_header AccessControlAllowOrigin *;
  3. }

上面的eot|ttf|woff|svg|otf,表示请求后缀类型,或者也可以直接写如下代码:

  1. location / {
  2. add_header AccessControlAllowOrigin *;
  3. }

SQL服务器出现OLE DB 访问接口 "SQLNCLI11" 无法启动分布式事务 - 华翎科技 - 博客园

mikel阅读(571)

来源: SQL服务器出现OLE DB 访问接口 “SQLNCLI11” 无法启动分布式事务 – 华翎科技 – 博客园

1)在windows控制面版–>管理工具–>服务–>Distributed Transaction Coordinator–>属性–>启动

(3)在客户端管理中选中“允许远程客户端”“允许远程管理”
(4)在事务管理通讯中选“允许入站”“允许出站”“不要求进行验证”
(5)保证DTC登陆账户为:NT Authority\NetworkService

右击DTC选择属性应用重启服务

测试是否通过,选择C:\Windows\System32\drivers\etc下的host文件,添加 IP  计算明

C++ Qt开发:SqlRelationalTable关联表组件 - lyshark - 博客园

mikel阅读(450)

来源: C++ Qt开发:SqlRelationalTable关联表组件 – lyshark – 博客园

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍SQLRelationalTable关联表组件的常用方法及灵活运用。

在上一篇文章中详细介绍了SQLTableModle组件是如何使用的,本篇文章将介绍SqlRelationalTable关联表组件,该该组件其实是SqlTableModle组件的扩展类,其提供了一个带关系的数据模型,用于处理数据库中的表与表之间的关系。通过这个类,你可以在一个表中使用外键关联到另一个表的数据上。例如将主表中的某个字段与附加表中的特定字段相关联起来,QSqlRelation(关联表名,关联ID,名称)就是用来实现多表之间快速关联的。

1.1 ComboBox

首先我们来实现一个简单的联动效果,数据库组件可以与ComboBox组件形成多级联动效果,在日常开发中多级联动效果应用非常广泛,例如当我们选择指定用户时,让其在另一个ComboBox组件中列举出该用户所维护的主机列表,又或者当用户选择省份时,自动列举出该省份下面的城市列表等。

在进行联动之前需要创建两张表,表结构内容介绍如下:

  • User(id,name)表:存储指定用户的ID号与用户名
  • UserAddressList(id,name,address)表:与User表中的用户名相关联,存储该用户所管理的主机列表信息

通过数据库组件实现的联动非常简单,初始化表结构得到了两张表,当程序运行时默认在MainWindow构造函数处填充第一个ComboBox组件,也就是执行一次数据库查询,并将结果通过addItem()放入到第一个组件内。

QSqlDatabase db;

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    InitMultipleSQL();

    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./database.db");
     if (!db.open())
     {
            std::cout << db.lastError().text().toStdString()<< std::endl;
            return;
     }

     QSqlQuery query;
     query.exec("select * from User;");
     QSqlRecord rec = query.record();

     while(query.next())
     {
         int index_name = rec.indexOf("name");
         QString data_name = query.value(index_name).toString();
         ui->comboBox_user->addItem(data_name);
     }
}

而当用户选中了第一个ComboBox组件时,则让其转到槽函数on_comboBox_activated(const QString &arg1)上面,如下图所示;

该槽函数需要一个传入参数,此参数代表组件选中的文本内容,通过利用该文本内容在数据库内执行二次查询并将查询结果填充之对应的第二个ComboBox组件内即可实现组件的联动选择效果,其槽函数代码如下所示;

void MainWindow::on_comboBox_user_activated(const QString &arg1)
{
    if(db.open())
    {
        QSqlQuery query;
        query.prepare("select * from UserAddressList where name = :x");
        query.bindValue(":x",arg1);
        query.exec();

        QSqlRecord rec = query.record();

        ui->comboBox_address->clear();
        while(query.next())
        {
            int index = rec.indexOf("address");
            QString data_ = query.value(index).toString();
            ui->comboBox_address->addItem(data_);
        }
    }
}

读者可自行运行案例中的SqlComboBox案例,运行后可自行选择不同的用户名,则此时会输出该用户名所对应的地址表,如下图所示;

1.2 TableView

接着,我们继续以TableView组件为例,简单介绍一下如何实现组件与数据的绑定,首先我们需要创建一个表并插入几条测试记录,运行如下代码实现建库建表.

创建一张新表,表结构内容介绍如下:

  • LyShark(name,age)表:存储指定用户名与用户年龄

在主构造函数中我们可以直接通过QSqlQueryModel来得到特定表中的记录,并通过setHeaderData将表中的数据关联到对应的数据模型内,最后通过setModel方法即可将对应的表数据关联到前端显示,其核心代码如下所示;

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Init();

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./database.db");
     if (!db.open())
     {
            std::cout << db.lastError().text().toStdString()<< std::endl;
            return;
     }

     // 查询数据表中记录
     qryModel=new QSqlQueryModel(this);
     qryModel->setQuery("SELECT * FROM LyShark ORDER BY id");
     if (qryModel->lastError().isValid())
     {
         return;
     }

     // 设置TableView表头数据
     qryModel->setHeaderData(0,Qt::Horizontal,"ID");
     qryModel->setHeaderData(1,Qt::Horizontal,"Name");
     qryModel->setHeaderData(2,Qt::Horizontal,"Age");

     // 将数据绑定到模型上
     theSelection=new QItemSelectionModel(qryModel);
     ui->tableView->setModel(qryModel);
     ui->tableView->setSelectionModel(theSelection);
     ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
}

运行代码后,程序会从数据库内取出结果并输出到tableView组件上,如下图所示;

1.3 SqlRelationalTable

在最开始我们也说过,SqlRelationalTable 并不是Qt中标准的类或方法。它仅仅只是QSqlTableModel的一个子类,其支持在关系数据库表之间建立关系,建立关联时我们只需要使用setRelation方法即可。

setRelation 是 QSqlRelationalTableModel 类中的一个方法,用于设置模型中某一列的关联关系。这个方法的目的是告诉模型某一列的值在另一个表中有关联,并提供相关的信息,以便在视图中显示更有意义的数据而不是外键的原始值。

以下是 setRelation 方法的简单说明:

void QSqlRelationalTableModel::setRelation(int column, const QSqlRelation &relation);
  • column: 要设置关联关系的列的索引。
  • relation: 包含关联信息的 QSqlRelation 对象。

QSqlRelation 的构造函数如下:

QSqlRelation::QSqlRelation(const QString &tableName, const QString &indexColumn, const QString &displayColumn);
  • tableName: 关联的表的名称。
  • indexColumn: 关联表中与当前表关联的列的名称,通常是外键列。
  • displayColumn: 关联表中要显示的列的名称,通常是与外键列相关的实际数据。

示例:

QSqlRelationalTableModel model;
model.setTable("orders");
model.setRelation(2, QSqlRelation("customers", "customer_id", "customer_name"));
model.select();

在这个例子中,第二列(索引为2的列)的数据将从名为 “customers” 的表中获取,该表的外键列为 “customer_id”,并且在视图中显示的是该关联表的 “customer_name” 列的值。使用 setRelation 方法可以使得在表格中更容易地显示和编辑关联数据,而不是直接显示外键的值。

在关联表之前,我们需要设置初始化数据,此处我们提供两个表结构,表Student用于存储学生名字以及学生课程号,另一张Departments则用于存储每个编号所对应的系名称,运行代码完成创建。

// 初始化数据表
void MainWindow::InitSQL()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./database.db");
    if (!db.open())
           return;

    // 执行SQL创建表
    db.exec("DROP TABLE Student");
    db.exec("CREATE TABLE Student ("
                   "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                   "name VARCHAR(40) NOT NULL, "
                   "departID INTEGER NOT NULL)"
            );

    // 逐条插入数据
    db.exec("INSERT INTO Student(name,departID) VALUES('zhangsan',10)");
    db.exec("INSERT INTO Student(name,departID) VALUES('lisi',20)");
    db.exec("INSERT INTO Student(name,departID) VALUES('wangwu',30)");
    db.exec("INSERT INTO Student(name,departID) VALUES('wangmazi',40)");

    db.exec("DROP TABLE Departments");
    db.exec("CREATE TABLE Departments("
            "departID INTEGER NOT NULL,"
            "department VARCHAR(40) NOT NULL)"
            );

    db.exec("INSERT INTO Departments(departID,department) VALUES (10,'数学学院')");
    db.exec("INSERT INTO Departments(departID,department) VALUES (20,'物理学院')");
    db.exec("INSERT INTO Departments(departID,department) VALUES (30,'计算机学院')");
}

接着我们来看下在MainWindow构造函数中是如何进行初始化和表关联的,以下是对代码的简要说明:

打开数据库连接

创建一个 SQLite 数据库连接,并指定了数据库文件的路径。如果数据库连接成功打开,就继续执行后面的代码。

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./database.db");
if (!db.open())
    return;

设置主窗口的布局和属性

将主窗口的中央部件设置为一个 QTableView,同时对表格的选择行为和外观进行了设置。

this->setCentralWidget(ui->tableView);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setAlternatingRowColors(true);

打开数据表并设置模型

创建一个 QSqlRelationalTableModel 并设置了一些表格的属性,包括表名、编辑策略、排序等。

tabModel = new QSqlRelationalTableModel(this, db);
tabModel->setTable("Student");
tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
tabModel->setSort(0, Qt::AscendingOrder);

tabModel->setHeaderData(0, Qt::Horizontal, "学号");
tabModel->setHeaderData(1, Qt::Horizontal, "姓名");
tabModel->setHeaderData(2, Qt::Horizontal, "学院");

设置查询关系数据表

设置关系型字段,将 “学院” 列与 “Departments” 表中的 “departID” 列关联起来,并在表格中显示 “department” 列的数据。

tabModel->setRelation(2, QSqlRelation("Departments", "departID", "department"));

设置表格的选择模型和代理

代码设置了表格的选择模型,并为表格设置了一个关系型代理(QSqlRelationalDelegate),以便在表格中显示关联表的数据而不是外键的值。

theSelection = new QItemSelectionModel(tabModel);
ui->tableView->setModel(tabModel);
ui->tableView->setSelectionModel(theSelection);
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));

选择并显示数据表

最后,通过调用 select 方法来选择和显示数据表的内容。

tabModel->select();

其实代码中最重要的部分就是setRelation,我们只要确保数据库文件正确,并且 Student 表和 Departments 表存在,并且在 Student 表中的 “学院” 列与 Departments 表中的 "departID" 列正确关联即可,其他的就交给组件来处理,如下图所示;

asp.net core 指定ip 端口启动 - 跟着阿笨一起玩.NET - 博客园

mikel阅读(553)

来源: asp.net core 指定ip 端口启动 – 跟着阿笨一起玩.NET – 博客园

1.dotnet run (项目有代码的才行)这种方式默认会加载launchSettings.json文件。

注意如果在执行dotnet run命令的时候不希望加载launchSettings.json文件,我们可以通过显式指定命令行参数–no-launch-profile来实现。

 

URL格式:

  • localhost:http://localhost:5000
  • 指定ip:在你机器上可用的指定IP地址(例如http://192.168.8.31:5005)
  • 任何ip:使用”任何”IP地址(例如http://*:6264

注意,针对”任何”IP地址的格式 – 你不一定必须使用*,你可以使用任何字符,只要不是IP地址或者localhost, 这意味着你可以使用http://*http://+http://mydomainhttp://example.org. 以上所有字符串都具有相同的行为,可以监听任何IP地址。如果你想仅处理来自单一主机名的请求,你需要额外配置主机过滤。

 

2.dotnet xxx.dll 已经编译好的dll,不指定ip,指定端口

3.指定ip和端口