QProcess用于启动一个外部程序,并提供了与之通信的接口。
使用setProgram来设置要启动的外部程序,setArguments来设置要传递给这个外部程序的参数。
setArguments需要一个QStringList类型的参数,在构造这个参数的时候要注意不能把外部程序需要的参数作为一整个字符串。
举个例子:要用QProcess执行find -name abc.txt

1
2
3
4
QProcess process;
process.setProgram("find");
process.setArguments(QStringList("-name abc.txt")); // 这是错误的
process.setArguments(QStringList() << "-name" << "abc.txt");

在osx系统下, qt程序菜单项的名字如果是“quit”,”about”(不区分大小写), 这个菜单项就会消失, 如果这个菜单只包含这些会消失的菜单项, 那么这个菜单也会消失.
猜测: 这应该是由于跟osx系统默认给程序提供了一些菜单项有冲突的关系.

问题示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SimpleMenu::SimpleMenu(QWidget *parent)
: QMainWindow(parent) {

// 只要菜单项的名字不是“Quit”或“quit”就可以正常显示
QAction *quit = new QAction("&Quit", this);
// 只要菜单项的名字不是“About”或“about”就可以正常显示
QAction *about = new QAction("&about", this);

QMenu *file;
file = menuBar()->addMenu("&File");
file->addAction(quit);
file->addAction(about);

connect(quit, &QAction::triggered, qApp, QApplication::quit);
}

更新:
可以使用rdnetto/YCM-Generator插件来自动生成.ycm_extra_conf.py

当前操作系统: osx 10.13

使用brew安装的qt5

qt安装目录在哪里不需要管, 因为使用brew更新qt后安装目录会随着版本变动而变动, 但不管哪个版本brew都会在/usr/local/opt/创建一个链接指向真正的目录, 我只安装了qt5, 所以上述目录下有两个链接, qt和qt5, 这两个目录都指向qt5的安装目录, 任选一个路径用于下面的命令即可, 这里使用这个路径:/usr/local/opt/qt.

执行一个命令来找到所有需要的库的路径:

1
find /usr/local/opt/qt/ -name "Headers" | grep "framework\/Headers" > ~/headers

执行完毕后会在HOME下生成headers文件, 文件的内容就是qt5所有的库的路径(头文件), 接下来就是将这些路径添加到ycm的配置文件.ycm_extra_conf.py里了, 下面是我修改好的, 保存为:.ycm_extra_conf.py放到项目目录下(或上级目录), ycm就会自动读取了.

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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
from distutils.sysconfig import get_python_inc
import platform
import os
import ycm_core

# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
# You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM
# source code needs it.
'-DUSE_CLANG_COMPLETER',
# THIS IS IMPORTANT! Without the '-x' flag, Clang won't know which language to
# use when compiling headers. So it will guess. Badly. So C++ headers will be
# compiled as C headers. You don't want that so ALWAYS specify the '-x' flag.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x',
'c++',
'-isystem',
'../BoostParts',
'-isystem',
get_python_inc(),
'-isystem',
'../llvm/include',
'-isystem',
'../llvm/tools/clang/include',
'-I',
'.',
'-I',
'./ClangCompleter',
'-isystem',
'./tests/gmock/gtest',
'-isystem',
'./tests/gmock/gtest/include',
'-isystem',
'./tests/gmock',
'-isystem',
'./tests/gmock/include',
'-isystem',
'./benchmarks/benchmark/include',
# for qt5 which installed by brew in mac
'-I', '/usr/local/opt/qt/include',
'-I','/usr/local/opt/qt/lib/Qt3DAnimation.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DCore.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DExtras.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DInput.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DLogic.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DQuick.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DQuickAnimation.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DQuickExtras.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DQuickInput.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DQuickRender.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DQuickScene2D.framework/Headers',
'-I','/usr/local/opt/qt/lib/Qt3DRender.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtBluetooth.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtCharts.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtConcurrent.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtCore.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtDataVisualization.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtDBus.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtDesigner.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtDesignerComponents.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtGamepad.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtGui.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtHelp.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtLocation.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtMacExtras.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtMultimedia.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtMultimediaQuick_p.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtMultimediaWidgets.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtNetwork.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtNetworkAuth.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtNfc.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtOpenGL.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtPositioning.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtPrintSupport.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtPurchasing.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtQml.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtQuick.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtQuickControls2.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtQuickParticles.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtQuickTemplates2.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtQuickTest.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtQuickWidgets.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtRemoteObjects.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtRepParser.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtScript.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtScriptTools.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtScxml.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtSensors.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtSerialBus.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtSerialPort.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtSql.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtSvg.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtTest.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtTextToSpeech.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtUiPlugin.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtWebChannel.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtWebEngine.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtWebEngineCore.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtWebEngineWidgets.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtWebSockets.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtWebView.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtWidgets.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtXml.framework/Headers',
'-I','/usr/local/opt/qt/lib/QtXmlPatterns.framework/Headers',
]

# Clang automatically sets the '-std=' flag to 'c++14' for MSVC 2015 or later,
# which is required for compiling the standard library, and to 'c++11' for older
# versions.
if platform.system() != 'Windows':
flags.append( '-std=c++11' )


# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# You can get CMake to generate this file for you by adding:
# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
# to your CMakeLists.txt file.
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''

if os.path.exists( compilation_database_folder ):
database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
database = None

SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]

def DirectoryOfThisScript():
return os.path.dirname( os.path.abspath( __file__ ) )


def IsHeaderFile( filename ):
extension = os.path.splitext( filename )[ 1 ]
return extension in [ '.h', '.hxx', '.hpp', '.hh' ]


def GetCompilationInfoForFile( filename ):
# The compilation_commands.json file generated by CMake does not have entries
# for header files. So we do our best by asking the db for flags for a
# corresponding source file, if any. If one exists, the flags for that file
# should be good enough.
if IsHeaderFile( filename ):
basename = os.path.splitext( filename )[ 0 ]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists( replacement_file ):
compilation_info = database.GetCompilationInfoForFile(
replacement_file )
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile( filename )


def FlagsForFile( filename, **kwargs ):
if not database:
return {
'flags': flags,
'include_paths_relative_to_dir': DirectoryOfThisScript()
}

compilation_info = GetCompilationInfoForFile( filename )
if not compilation_info:
return None

# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object.
final_flags = list( compilation_info.compiler_flags_ )

# NOTE: This is just for YouCompleteMe; it's highly likely that your project
# does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
# ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT.
try:
final_flags.remove( '-stdlib=libc++' )
except ValueError:
pass

return {
'flags': final_flags,
'include_paths_relative_to_dir': compilation_info.compiler_working_dir_
}

场景:
osx,deepin linux, windows三系统, 需要扩大黑苹果的分区.

osx下的磁盘工具简直不能更难用,有下面几个坑,很重要,要想扩容osx系统分区需要知道这些:

  • 不识别空分区,分区必要格式化,否则磁盘工具不识别
  • 必须是系统分区后面的分区才能合并到系统分区里
  • 要合到系统分区的分区必须和系统分区统一格式!!

上面三个坑, 尤其是第三个, 搞得我差点重装osx, 磁盘工具竟然不自动格式化分区就直接和osx的系统盘合并了,
导致虽然系统盘容量增大了, 但却出现一个分区里却有两块不同格式的磁盘空间, 幸好我记得合并进去的分区是多大,
又动手压缩出来了, 然后格式化为osx系统分区格式, 再次合并才成功

osx下的磁盘工具虽然难用, 但是要扩大osx系统分区只能用这个工具, 不像linux或windows可以在livecd或者pe下调整.

正文:
草草画了几个图, 当时操作的时候没有截图, 下面这张图是我的硬盘的分区:
origin

既然是扩容osx分区, 那就需要从其他分区压缩出来一部分空间, 推荐在linux下使用gparted工具压缩和移动分区,
当然windows下也可以, 可以用diskgenius软件操作.
我需要从linux分区中压缩出来100G分给osx, 那么我就压缩之后的样子如下图:
yasuo

虽然压缩出来的空间已经挨着osx的分区了, 但是osx的磁盘工具不能将osx之前的分区合并到osx的系统分区中,
所以仅仅是压缩出来是不够的, 还需要将压缩出来的分区移动到osx分区之后, 且紧挨着osx分区, 移动后如下图:
yidong

然后格式化那块压缩出来的空间, 如果gparted或者diskgenius不支持当前osx分区的格式, 那就格式化成fat32格式,
格式化完成之后就可以启动到osx系统了, 打开磁盘工具, 将那块压缩出来的分区的格式改成当前osx分区的格式,
切记!! 一定要与当前osx分区的格式相同!!
然后点击磁盘工具上的‘分区’按钮, 再点击那块格式化好的压缩出来的分区, 再点一下’+‘旁边的’-‘号按钮,
也就是删除这个分区, 点击确定就行了, 删除这个分区后磁盘工具就会将其合并到osx的分区了.
大功告成, 如下图:
zuihou

本文不一定适用于所有电脑,需要自己找到对应的设备文件

我的电脑中,风扇对应到linux下的设备文件的路径是:

1
/sys/class/hwmon/hwmon2/pwm1

其他电脑即便不是这个文件,也在类似的目录下,这个文件的内容是”0-255“的数值,
相应的数值大小对应相应的风扇转速,向这个文件中写入不同的数据风扇就控制风扇的转速了。

我的电脑中这个文件的默认值是”85“。

下面附上我写的一个shell脚本,放到PATH里就可以方便的控制风扇转速了:

1
2
3
4
5
#!/bin/bash

read -p "input speed(0-255) and ENTER: " SPEED
[[ -z $SPEED ]] && SPEED=85
echo $SPEED | sudo tee /sys/class/hwmon/hwmon2/pwm1

注意如果上述提到的设备文件不同,需要修改脚本中的路径。
将上述代码保存为一个shell文件,如fancontrol.sh,并为其增加可执行权限:

1
chmod a+x fancontrol.sh

然后复制到PATH下,如/bin下。

阅读全文 »

本文是学习这篇博客所得的收获:
Android:Layout_weight的深刻理解

当子控件有layout_weight属性时, 系统将先按照layout_widthlayout_hight属性
先把子控件放到父控件中, 之后才解析layout_weight属性, 然后计算父控件中的剩余空间,
最后按比例分配剩余空间给子控件.

看一下处理layout_weight时所用到的公式:

1
2
3
4
5
6
7
8
9
# 实际尺寸: 子控件最终展示出来的尺寸
# 当前尺寸: 子控件刚被放到布局中, 系统还没有解析其weight属性时的尺寸
# weight比例: 子控件在所有有`layout_weight`属性的控件中所占的比例
# (例: 三个子控件, 第一个比重为1, 第二个为2, 第三个为2,
# 那么第一个所占比例为1/5, 第二个为2/5, 第三个为2/5)
# 剩余空间: 子控件刚被放到父控件中, 系统还没有解析其weight属性时父控件还有多少剩余空间

剩余空间 = 父控件尺寸 - 子控件1尺寸 - 子控件2尺寸 - 子控件3尺寸...
实际尺寸 = 当前尺寸 + weight比例 * 剩余空间尺寸

当控件的layout_width以及layout_hight的值为0或者wrap_content时,
layout_weight属性很容易预测最终效果, 它们会按照自己的weight比例
分配剩余空间尺寸.

需要留意的是当控件的layout_widthlayout_hight的值为fill_parent的时候,
此时每个子控件在刚被放到父控件中, 且系统还没有解析子控件的layout_weight时,
父控件就已经没有剩余空间了,

因为此时所有子控件的当前尺寸都等于父控件的尺寸, 且第一个子控件就已经占满了父控件!

那么套用上述公式, 计算子控件最终实际尺寸的过程如下:

下面假设一个父控件中有三个子控件, 其比重为1 : 2 : 3,
则子控件的weight比例依次为1/6, 2/6, 3/6

剩余空间的计算如下:

1
2
3
4
5
剩余空间 = 父控件尺寸 - 子控件1当前尺寸 - 子控件2当前尺寸 - 子控件3当前尺寸
# 上述等同于:
剩余空间 = 父控件尺寸 - 父控件尺寸 - 父控件尺寸 - 父控件尺寸
# 则(注意是负2):
剩余空间 = -2 * 父控件尺寸
阅读全文 »

一张图解释Dockerfile中CMD和ENTRYPOINT的关系,
另外使用’docker run’新建容器时, 镜像后面跟的命令会覆盖Dockerfile中的CMD.
docker

使用如下命令启动一个php容器, 并将php项目的目录映射到容器内的apache容器下:

1
docker run -p 80:80 --name php_app -v "/project/directory":/var/www/html -d php

然后访问127.0.0.1, 结果网站无法运行, 提示:Permission denied,

进入正在运行的php容器, 去看看项目目录在容器里的权限是什么:

1
2
3
docker exec -it php_app bash
cd /var/www/html
ls -l

发现文件的拥有者和属组都无法识别, 直接显示的UID和GID, 都是1000,
这是因为项目文件在容器外, 也就是主机本地的拥有者和属组是都是我的用户,
而我的用户的UID和GID在主机中是1000,
但是php容器里却没有我这个账户, 所以也就无法正常识别所有者了,
自然网站无法正常运行. 要想解决这个问题就得知道php这个容器
使用的是哪个用户来启动apache和php服务, 经过搜索得知是”www-data”用户,
那么修改这个用户的UID和GID为我的就行了(这里都是1000):

1
groupmod -g 1000 www-data && usermod -u 1000 -g 1000 www-data

然后重启php容器即可:

1
docker restart php_app

当前操作系统: deepin基于debian

模块管理器pip

默认的命令pip可能是来自pip2也可能是pip3, 这取决于安装pip2和pip3的顺序,
安装pip2或pip3时会覆盖原有pip可执行文件, 所以在使用pip安装python模块时,
最好明确指出使用pip2还是pip3, 而不是直接使用pip命令, 这样可以避免明明要安装python3的模块库, 下载安装的却是python2的模块库.

安装模块(库)

使用pip命令安装模块时, 是否使用sudo提权会影响安装路径.

使用sudo提权

会安装模块到以下路径:

1
2
/usr/lib/python*(版本不同,具体目录不同)
# python自带的一些模块文件在这个路径下.
1
2
/usr/local/lib/python*(版本不同,具体目录不同)
# 用户自行安装的模块一般在这个路径下.

没有使用sudo提权

阅读全文 »

cocos2d-x v3.15版, 在linux下编译之后执行test里的demo时报错:

1
2
3
$ ./cpp-tests 
./cpp-tests: error while loading shared libraries: libfmod.so.6:
cannot open shared object file: No such file or directory

从报错可以看出缺少libfmod.so.6这个库文件, 网上搜索后得知这个文件在:
$COCOS2D_HOME/external/linux-specific/fmod/prebuilt/64-bit目录下,
而且是在执行$COCOS2D_HOME/build/install-deps-linux.sh时发生报错的,

他们的解决办法是将上述目录下的两个库文件libfmod.solibfmodL.so,
复制到/usr/local/lib/目录下, 并创建链接文件, 然后接着执行install-deps-linux.sh,
但是这个方法对我没有作用, 可能是因为我是用的系统的缘故(deepin linux).

如果上述方法对你也没用就试试下面的方法:
复制两个库文件到/usr/lib/目录下, 然后创建链接文件:

1
2
3
4
#在cocos2d目录下执行
cp external/linux-specific/fmod/prebuilt/64-bit/* /usr/lib/
cd /usr/lib
ln -s libfmod.so libfmod.so.6

然后就可以直接测试demo了, 不用重新编译