使用CSS定制某类元素下的input文件选择控件

这几天在玩儿Alpaca表单生成器,可以从一个配置文件生成一个让用户填写的Web表单,再将填写好了的内容转换成Json

Alpaca内置“文件”类型的输入控件,可以用来设置文件什么的。我是想把这个表单嵌入到QtWenEngineView里面用,但是QtWenEngineView的实现有点问题(现在是2019年07月18日,Qt 5.13.0),所有<input type="file">控件的按钮都被只显示为一个小方块,没有提示文字,很难看。找了半天没看到有针对性的修复方法,只好想办法自己画一个。但表单是自动生成的,手写肯定不行,最合适的路径就是附加一个CSS。

Alpaca生成的表单中,每个项目是这样一个结构:

<div class="form-group alpaca-field alpaca-field-file alpaca-optional fuck alpaca-autocomplete alpaca-field-valid" data-alpaca-field-id="alpaca3" data-alpaca-field-path="/name" data-alpaca-field-name="name">
        <label class="control-label alpaca-control-label" for="alpaca3">项目名称</label>
        <input type="file" id="alpaca3" name="name" class="alpaca-control" autocomplete="off">
</div>

一个大div包含两个项目,分别是提示标签和输入控件。通过配置文件可以为外面那个大div附加一个class属性,上面的fuck属性便是。显然,需要构造一个CSS选择器,特异性地指向任意fuck类对象下的<input type="file">元素。经过一番搜索,发现.fuck input[type=file]可以传达这个意思。

于是任务就明确了:把原来的按钮隐藏掉,位置腾出来,然后自己画一个新的按钮并写上文字:

    <style type="text/css">
        ::-webkit-file-upload-button {
            width: 3.5em;
            visibility: hidden;
        }
 
        .file-button input[type=file]::before {
            content: '浏览';
            display: inline-block;
            background: linear-gradient(top, #f9f9f9, #e3e3e3);
            border: 1px solid #999;
            border-radius: 3px;
            padding: 5px 8px;
            outline: none;
            white-space: nowrap;
            -webkit-user-select: none;
            cursor: pointer;
            text-shadow: 1px 1px #fff;
            font-weight: 700;
            font-size: 10pt;
        }
    </style>

其中,::-webkit-file-upload-button控制所有文件选择按钮,把它隐藏掉但是把宽度留出来,否则选择过后显示的文件名会与其他部分重叠。下面的一大堆则是画一个新的按钮。任务完成。

很可惜的是,上面的折腾并未解决我的问题,原因是我想用这个方法让用户在Qt中输入一个文件路径,但浏览器都是不允许JS操作本地文件的。要实现这种功能,还需要动用更多的黑科技:

在Qt Webengine中使用Alpaca获取本地文件路径

  • 最后更改: 2019/07/20 13:54