化石原创文章,转载请注明来源并保留原文链接


必须使用ico文件,最简单的ico文件生成可以通过该网站:

https://favicon.io/favicon-generator/

有了ico文件后。只要按照下面做即可:

1、放置ico文件到项目根目录(这个在项目的什么位置不强制,可以在后面改动)

2、在项目根目录写一个rc文件(这个文件位置也不强制),里面内容如下(以ico文件在根目录为例)

 IDI_ICON1          ICON   DISCARDABLE   "app.ico" 

这里ico文件的名字叫做app.ico,必须是根目录下的ico文件的全名

3、打开项目的pro文件,在后面加入

 RC_FILE += resource.rc

这里意味着我们在第二步写的rc文件全名叫做resource.rc,你可以取任何其他名字。

Windows完成。

如果是MacOS,使用如下步骤:

1、找到一个大一点的png图做图标的种子,比如512×512的,或者1024×1024的,假设名字叫pic.png

2、在该png目录,建立一个目录,名字icons.iconset

3、使用一下命令(应该是mac自带,不然就是开发命令行套件带的)

 sips -z 16 16 pic.png --out icons.iconset/icon_16x16.png
 sips -z 32 32 pic.png --out icons.iconset/icon_16x16@2x.png
 sips -z 32 32 pic.png --out icons.iconset/icon_32x32.png
 sips -z 64 64 pic.png --out icons.iconset/icon_32x32@2x.png
 sips -z 64 64 pic.png --out icons.iconset/icon_64x64.png
 sips -z 128 128 pic.png --out icons.iconset/icon_64x64@2x.png
 sips -z 128 128 pic.png --out icons.iconset/icon_128x128.png
 sips -z 256 256 pic.png --out icons.iconset/icon_128x128@2x.png
 sips -z 256 256 pic.png --out icons.iconset/icon_256x256.png
 sips -z 512 512 pic.png --out icons.iconset/icon_256x256@2x.png
 sips -z 512 512 pic.png --out icons.iconset/icon_512x512.png
sips -z 1024 1024 pic.png --out icons.iconset/icon_512x512@2x.png 

这一系列命令会在刚才建立的目录下生成各个不同只存的png图,用来做最后的icon的输入。这里不是所有的png都需要生成。

4、使用下面的命令,生成最后的图标文件

  iconutil -c icns icons.iconset -o icon.icns 

5、拷贝生成的icon.icns文件到项目的根目录

6、pro文件中加入下面的一行

ICON = icon.icns
MacOS的完成。

这里要注意的是,如果已经有了编译出的debug、release中间文件,可能一次编译并不能马上是图标生效。最有效的方式是删除这些目录,再编译,能马上看到图标生效。

参考(官方文档):

https://doc.qt.io/qt-5/appicon.html

注意这个文档中还提到了一个imagemagick工具,可以中png转化ico文件。


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


Qt写应用,常见的需求是控件不是当前焦点的时候,也需要侦测按键、鼠标事件。这种需求只要使用eventFilter即可。

1、Widget头文件中,加入

protected:

     bool eventFilter(QObject *obj, QEvent *event);

2、Widget构造中,写上

qApp->installEventFilter(this);

注意,这里的qApp可以看做全局变量,实际上是个宏,在qcoreapplication.h中:

#define qApp QCoreApplication::instance()

这里使用qApp的原因是只要应用是焦点,那么该Widget就能得到事件,不管层级、不管控件自身是否有焦点。

3、具体的过滤方法大致样子

bool TextExplorer::eventFilter(QObject *obj, QEvent *e) {
    if (e->type() == QEvent::KeyPress) {
        QKeyEvent* event = (QKeyEvent*) e;
        if (event->key() == Qt::Key_Right) {
            
        }
        else if(event->key() == Qt::Key_Left) {
           
        }
    }
}

化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


本文适用于使用CKEditor5的官方默认向导生成的CKEditor5,但也可能对其他方式的有同样的意义。

对于上传图片这一块,这个默认的带上了ckfinder作为前端的上传插件。

假设我们的上传api,url是:/api/upload

那么,客户端只要这么配置:

var uploadApi = document.location.origin + "/api/upload";

ClassicEditor.create( document.querySelector( '#article-editor' ), {

				toolbar: {
					items: [
						'heading',
						'|',
						'bold',
						'italic',
						'link',
						'bulletedList',
						'numberedList',
						'|',
						'indent',
						'outdent',
						'|',
						'imageUpload',
						'blockQuote',
						'insertTable',
						'mediaEmbed',
						'undo',
						'redo'
					]
				},
				language: 'en',
				image: {
					toolbar: [
						'imageTextAlternative',
						'imageStyle:full',
						'imageStyle:side'
					]
				},
				ckfinder: {
                    uploadUrl: uploadApi,
				},
				table: {
					contentToolbar: [
						'tableColumn',
						'tableRow',
						'mergeTableCells'
					]
				},
				licenseKey: '',

			} )
			.then( editor => {
				window.editor = editor;
			} )
			.catch( error => {
				console.error( 'Oops, something gone wrong!' );
				console.error( 'Please, report the following error in the https://github.com/ckeditor/ckeditor5 with the build id and the error stack trace:' );
				console.warn( 'Build id: k2i30chx32nf-8o65j7c6blw0' );
				console.error( error );
			} );

其实对于前端,就是给ckfinder配上一个url,就这么简单。

后台这块ASP.net,Java,PHP官方有文档,不过说实话一点都不友好。所以自给自足:

    @PostMapping("/api/upload")
    private String uploadImage(@RequestParam MultipartFile[] upload) {
        String originalFileName = upload[0].getOriginalFilename();
        String fileExtensionName = originalFileName.substring(originalFileName.lastIndexOf("."), originalFileName.length()).toLowerCase();;//上传图片的文件扩展名

        String newFileName = java.util.UUID.randomUUID().toString()+fileExtensionName;
        String uploadPath = imageUploaPath;
        String imageUrl = imageUploaPath + newFileName;
        File pathFile = new File(uploadPath);
        if (!pathFile.exists()) { // 如果路径不存在,创建
            pathFile.mkdirs();
        }
        try {
            File dest = new File(imageUrl);
            upload[0].transferTo(dest);
        } catch (IOException e) {

        }

        JSONObject jo = new JSONObject();
        jo.put("uploaded", true);
        jo.put("url", newFileName);

        return jo.toJSONString();
    }

代码是SpringBoot工程萃取出来的,已经删去了不必要的代码。尽量只展现这部分的有效信息。

最有用的信息是返回值格式:ckeditor5希望的格式其实是这样的json

{
    "uploaded": true,
    "url": "xxxxx"
}

这个是成功的返回格式。如果错误,则是下面:

 {
    "uploaded": false,
    "error": {
        "message": "xxxx"
    }
} 

代码中,imageUploadPath是@Autowired来的

@Value("${web.upload-path}")
private String imageUploaPath;

在application.properties是这样:

web.upload-path=f:/imageUpload/
spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${web.upload-path}

那个JSONObject用了Maven里面的json-simple

<!-- https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple -->
<dependency>
    <groupId>com.googlecode.json-simple</groupId>
    <artifactId>json-simple</artifactId>
    <version>1.1.1</version>
</dependency>

化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


一个网站,后台没有使用vue写界面,前端界面使用了Vue.js。

架设到IIS上后,发现大多正常,前台、后台都能访问。唯一的问题就是属于vue写的那块页面,只要F5刷新就出现404错误。


查了一下是IIS的安全机制引起,可以使用IIS的URL Rewrite工具解决。

URL Rewrite可以通过IIS管理器,找到Web 平台安装程序这个入口,然后“产品”页面,选中“服务器”,可以找到“URL重写工具 2.0”。如果没有安装,点后面的“安装”即可。

然后到IIS管理器,对应的网站选中后,找到“URL重写”按钮,加入规则。

这里假设我们遇到的F5刷新出问题的url都是hostname/CourseBase/xxx这样的,那么就加入如下规则(选空白规则创建):

1、名称:随便填

2、匹配url:默认状态下,模式填入:^CourseBase/*

3、条件:点击添加,加入“不是文件”

4、操作:重写。重写url中填根目录文件,比如/index.html。

如此操作好,IIS就会在我们的网站web.config.中写入下面内容:

<rewrite>
  <rules>
	  <rule name="F5">
		  <match url="^CourseBase/*" />
			<conditions>
				<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
			</conditions>
			<action type="Rewrite" url="/Index.html" />
		</rule>
	</rules>
</rewrite>

应用后就能生效。


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


three.js官方demo的gltf中,使用了hdr图做背景。跟原图(HDR)比,这个背景在实时演示中,是明显模糊了。

这个问题的原因在于:

new RGBELoader()
	.setDataType( THREE.UnsignedByteType )
	.setPath( 'textures/equirectangular/' )
	.load( 'pedestrian_overpass_1k.hdr', function ( texture ) {

		var envMap = pmremGenerator.fromEquirectangular( texture ).texture;

		scene.background = envMap;
		scene.environment = envMap;

这段代码中,envMap的精度被底层控制在了256像素。

使用下面的方式可以提高精度:

envMap = new THREE.WebGLCubeRenderTarget( 1024 ).fromEquirectangularTexture( renderer, texture );

其中的texture就是上面的代码中回调产生的texture,代码里把精度提升到了1024。


化石原创文章,转载请注明来源并保留原文链接