scienceasdf


  • 首页

  • 分类

  • 归档

  • 标签

一些Qt在Ubuntu下的问题

发表于 2018-09-18 | 分类于 Math

In this post we will talk about some problems occured in Ubuntu OS when writing Qt program.本文讨论一些在ubuntu使用Qt的问题。


qDebug的使用

通常而言,实际上qDebug是不能直接输出std::string的,但是在Windows和Android上直接拿来用没有遇到过问题。。。在Ubuntu上使用会报错,因此需要重载«操作符:

QDebug operator<<(QDebug out, const std::string& str)
{
    out << QString::fromStdString(str);
    return out;
}

ssl的使用

在把paperServer服务器从Win/Android移植到Linux下遇到了问题,如果访问https连接的话,会发现ssl的函数没有实现。具体的,发现自己其实已经安装了openssl,libssl-dev的包,可是还是不对。我们输出一下相关的信息:

qDebug()<<"SSL version use for build: "<<QSslSocket::sslLibraryBuildVersionString();
qDebug()<<"SSL version use for run-time: "<<QSslSocket::sslLibraryVersionNumber();
qDebug()<<QCoreApplication::libraryPaths();

发现Qt的ssl是基于1.0版本的,而apt得到的是1.1版本的,二者并不兼容。因此需要安装sudo apt-get install libssl1.0-dev,会把原来的ssl库卸载掉,而且还会连带卸载petsc库。。。。。。解决方法是系统中安装openssl1.1,而自己编译一个openssl1.0.2的so,一定要动态编译(./config shared),不然无法链接,因为我Qt是编译的动态库。然后很坑的是设置elf的RUNPATH居然不管用,必须要export LD_LIBRARY_PATH=$PWD才能让程序正确地链接到同目录下的ssl。真是天坑。。。

阅读全文 »

切比雪夫多项式、节点与插值

发表于 2018-09-15 | 分类于 Math

In this post we discuss on Chebyshev polynomials, nodes and interpolation.讨论关于切比雪夫多项式、节点与插值


切比雪夫节点

对于拉格朗日插值公式,如何选取节点是一个重要的问题。通常而言,等距选取节点并不是一个最优的选择。我们考虑如下的问题描述: 取插值节点:$a\leq x_0\leq x_1\leq ……\leq x_n\leq b$ 满足$L_n(x_k)=f(x_k)$的多项式插值余项

其中,

选取$x_0,x_1,……,x_n$使

因此需要选取切比雪夫多项式$T_{n+1}(x)$的全部零点。

如果$a=-1,b=1$,那么

如果$[a,b]\neq [-1,1]$,那么

当然选取了节点之后既可以用拉格朗日插值,也可以用牛顿插值。

切比雪夫多项式

在微分方程的研究中,切比雪夫提出切比雪夫微分方程

和

相应地,第一类和第二类切比雪夫多项式分别为这两个方程的解。 这些方程是斯图姆-刘维尔微分方程的特殊情形。本文只研究第一类切比雪夫多项式。

第一类切比雪夫多项式由以下递推关系确定

也可以用母函数表示

切比雪夫多项式也具有正交性,即

离散形式的正交性可以表示为

根据正交性,可以得到另外一种方法来进行拉格朗日插值。设 ,易得

阅读全文 »

再谈C++的字符串分割

发表于 2018-08-25 | 分类于 Programming

再次讨论如何分割C++的std::string.


一些别的方法我们之前已经讨论过了,例如Boost::tokenizer或者Boost::splitter或者QString来进行分割。不过这里我们讨论一下运用C++标准库的方法。

思路很简单,就是用istream流的迭代器处理。

思路1

首先一个比较简单的用法是

std::string text = "Let me split this into words";

std::istringstream iss(text);
std::vector<std::string> results((std::istream_iterator<std::string>(iss)),std::istream_iterator<std::string>());

如果使用C++11语法可以写成这样:

std::string text = "Let me split this into words";

std::istringstream iss(text);
std::vector<std::string> results((std::istream_iterator<std::string>{iss}),std::istream_iterator<std::string>());

这种思路的优点是可以处理任何流而不仅仅是字符串,但是缺点是不能自定义分隔符。

思路2

std::istream& operator>>(std::istream& is, std::string& output)
{
   // ...does lots of things...
}

这段代码肯定是不能改的,因为这是标准库里的东西。不过我们可以变通一下:

class WordDelimitedByComma : public std::string
{};

这样做实际上是有争议的,因为std::string没有一个虚的析构函数,因此最好不要从std::string继承。当然,只要不去删除一个指向WordDelimitedByComma的指针,就不会出现问题。在这里我们只用来分割字符串。重载«操作符:

std::istream& operator>>(std::istream& is, WordDelimitedByComma& output)
{
    std::getline(is, output, ',');
    return is;
}

因此代码可以写成

std::string text = "Let,me,split,this,into,words";

std::istringstream iss(text);
std::vector<std::string> results((std::istream_iterator<WordDelimitedByComma>(iss)), std::istream_iterator<WordDelimitedByComma>());

更为通用的代码可以写成

template<char delimiter>
class WordDelimitedBy : public std::string
{};

std::string text = "Let,me,split,this,into,words";

std::istringstream iss(text);
std::vector<std::string> results((std::istream_iterator<WordDelimitedBy<','>>(iss)), std::istream_iterator<WordDelimitedBy<','>>());

这个的优点是

  • 允许在编译器定义任意的分隔符
  • 可以使用任何流而不仅仅是字符串
  • 比方法1快20%至30%

而缺点是分隔符只能在编译器定义,且代码量较大。

思路3

std::vector<std::string> split(const std::string& s, char delimiter)
{
    std::vector<std::string> tokens;
    std::string token;
    std::istringstream tokenStream(s);
    while(std::getline(tokenStream, token, delimiter)){
        tokens.push_back(token);
    }
    return tokens;
}

这个思路的有点在于

  • 接口清晰
  • 能够在运行期使用任何分隔符
阅读全文 »

初窥Qt WebAssembly

发表于 2018-08-23 | 分类于 Programming

Qt 5.11发布了Qt WebAssembly的技术预览(Technology Preview)。对Qt WebAssembly的代码进行了编译并编译了一些程序。


安装最新emscripten

开发机系统为Ubuntu 18.04,直接用apt install 得到的emscripten版本太老,因此需要最新版本的emscripten.下载解压后

./emsdk update
./emsdk install latest
./emsdk activate latest

然后设置环境变量,可以source ./emsdk_env.sh

编译Qt-WebAssembly源码

首先下载好源码,然后坑也不少。按照官方wiki的命令编译不了,需要用命令./configure -xplatform emscripten -developer-build -release -static -no-thread -nomake tests -nomake examples -no-dbus -no-headersclean -system-libpng -no-ssl -no-warnings-are-errors编译。编译的时候会提示不能确定指令集架构,是因为用了emscripten1.38的原因,需要在qtbase文件夹下的configure.pri修改

else: html5:exists($$test_out_dir/arch.js.mem): \
content = $$cat($$test_out_dir/arch.js.mem, blob)

改成

html5:exists($$test_out_dir/arch.wasm): \
content = $$cat($$test_out_dir/arch.wasm, blob)

就可以configure然后make了。

编译一个具体的程序

编译程序用命令

/qtbase/bin/qmake 
make

然后可以用命令python -m SimpleHTTPServer启动一个简单的http服务器。

不过编译的时候也有坑,不知道为什么,include目录不能有/usr/include,具体只能加上自己的目录,例如/usr/include/eigen3.这个问题的原因目前没有明白。

实际效果

我把easyAuto给编译成了wasm文件。具体的文件包括有easyAuto.js, easyAuto.wasm, easyAuto.html, qtloader.js, qtlogo.svg.最后的效果见网站。在easyAuto中的QtChart不能使用openGL加速绘制。此外还有的坑包括

  • iOS设备不支持wasm
  • 移动设备打开网页后,文本框无法触发虚拟键盘。这是因为整个Qt程序是一个canvas,其中的文本框不是dom对象,因此文本框只能用外部键盘输入,或者自己画一个键盘。。。。。。。
  • Qt程序不能调用系统的字体,程序里面自带了英文字体,而中文字体则无法显示。奇怪的是我在程序里面加上中文字体一起打包编译仍然显示中文不出。好像是需要在源码中改/qtbase/src/plugins/platforms/html5/font里面的qrc,具体是不是我也不知道。。。。。。
  • wasm文件很大,不过倒是可以在服务器端压缩。
  • 在手机上运行很卡,而且有的demo甚至会闪退。
  • 无法获取本地文件,解决方法见这里。

总的感觉坑还是不少,不过这个只是技术预览,最终版希望能够有很大改进。这里给出几张easyAuto-WebAssembly程序的截图吧。

阅读全文 »

最近使用Ubuntu的一些总结

发表于 2018-06-02 | 分类于 Programming

最近使用Ubuntu系统的一些小技巧总结。


编译最新CMake

sudo apt remove cmake
sudo apt purge --auto-remove cmake
version=3.11
build=1
mkdir ~/temp
cd ~/temp
wget https://cmake.org/files/v$version/cmake-$version.$build.tar.gz
tar -xzvf cmake-$version.$build.tar.gz
cd cmake-$version.$build
./bootstrap
make -j16
sudo make install
cmake --version

创建快捷方式

sudo apt-get install --no-install-recommends gnome-panel
gnome-desktop-item-edit --create-new ~/桌面

从HDMI输出声音

sudo apt-add-repository ppa:yktooo/ppa
sudo apt update
sudo apt install indicator-sound-switcher

利用indicator-sound-switcher便可以在各个通道切换声音输出。注意Ubuntu 18.04添加ppa以后不需要sudo apt update这一步了。

阅读全文 »

泊松方程的有限元求解(理论)

发表于 2018-04-27 | 分类于 Math
阅读全文 »

实现一个简单的在线请假系统

发表于 2018-04-26 | 分类于 Programming

实现了一个B/S架构的在线请假申请系统。路子十分野,所以只是用于这种极为特殊的个人项目里面。


自从上次发现了qhttpserver之后,便增加了很多可以玩的东西。以前有个同学找我希望我做一个在线的请假申请系统,当时我还比较弱,只会C++/Qt和sqlite开发,想的架构是C/S架构的,我想了想,这个不能跨平台,不便于产品更新,而且即使这样我也做不出来。现在写过网页,写过http server的程序,这个东西我想了想,还是能够实现的。

基本需求

用户访问页面,填写相关信息,并且需要附上说明请假情况的图片,通过post请求发送到服务器。

用户选择图片并在预览

首先需要一个文件输入框<input type="file" id="take-picture" accept="image/*">,用户点击按钮可以通过调用摄像头或者选择存储空间中的图片。选择了图片之后还需要预览,预览的相关代码如下:

(function () {
    var takePicture = document.querySelector("#take-picture"),
        showPicture = document.querySelector("#show-picture");

    if (takePicture && showPicture) {
        // Set events
        takePicture.onchange = function (event) {
            // Get a reference to the taken picture or chosen file
            var files = event.target.files,
                file;
            if (files && files.length > 0) {
                file = files[0];
                try {
                    // Get window.URL object
                    var fileReader = new FileReader();
                    fileReader.onload = function (event) {
                        showPicture.src = event.target.result;
                    };
                    fileReader.readAsDataURL(file);
                    imageFlag = true;
                }
                catch (e) {
                    try {
                        // Fallback if createObjectURL is not supported
                        var fileReader = new FileReader();
                        fileReader.onload = function (event) {
                            showPicture.src = event.target.result;
                        };
                        fileReader.readAsDataURL(file);
                    }
                    catch (e) {
                        //
                        window.alert("ca)");
                        var error = document.querySelector("#error");
                        if (error) {
                            error.innerHTML = "Neither createObjectURL or FileReader are supported";
                        }
                    }
                }
            }
        };
    }
})();

我经过实际的测试,发现本来预览图片应该有两种方法的,但是实际上在手机上获取window.URL既不抛出异常,也不能加载图片,因此就直接用readAsDataURL的方法。

关于信息的上传

这里我用的是野得不能再野得路子了。通常的解决方案是生成multipart/form-data数据,但是这个方法我不用的原因是服务器端我没有使用任何PHP(目前还没有学习PHP的必要),C++来parse这个东西又需要另外写代码,比较麻烦,因此直接将单独的图片数据post到服务器。图片的post也是个大麻烦,理论上xhr可以直接send类型为file的对象的,但是实际上却在我的手机上不支持。因此,还是需要用下面的办法,就是readAsArrayBuffer,然后调用回调函数发送请求。

var fileReader2 = new FileReader();
fileReader2.readAsArrayBuffer(document.getElementById("take-picture").files[0]);
fileReader2.onloadend = function (event) {
    var xhr2 = new XMLHttpRequest();
    xhr2.onreadystatechange = function () {
        if (xhr2.readyState == XMLHttpRequest.DONE) {
            swal(xhr2.response);
        }
    }
    xhr2.open("POST",  encodeURI(queryStr));
    xhr2.send(event.target.result);
}

接下来的问题就是其他信息的上传。本来想用header来发送的,不过却发现手机上连header都发不了(我感觉这里很有可能是我自己代码的问题,手机浏览器怎么可能不能发送请求头

阅读全文 »
1 2 3 4 … 7
scienceasdf

scienceasdf

We will bury them !

45 日志
10 分类
RSS
GitHub ZhiHu 404公益@宝贝回家 神奇的网页
© 2017 - 2020 scienceasdf
由 Jekyll 强力驱动
主题 - NexT.Pisces