如果是一个已经存在的qt项目,可以使用open目前的目录就可以。
在 .pro文件中可以定义这些,注意自己的头文件放置位置。
code:
#-------------------------------------------------
#
# Project created by QtCreator 2021-03-02T15:53:39
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = AgoraCall3
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
...
devicestestworker.cpp \
capturedesktopworker.cpp
HEADERS += \
agoracall.h \
playmediaworker.h \
captureaudioworker.h \
capturevideoworker.h \
...
capturedesktopworker.h
FORMS += \
agoracall.ui \
dialogstreamsetting.ui \
localwindow.ui \
dialogdevicestest.ui
INCLUDEPATH = += /usr/include/eswin ../agora_sdk ../agora_sdk/include ../include .
contains(QMAKE_HOST.arch, aarch64) {
LIBS += -L/usr/lib/eswin/aarch64 -leswinsdk -L../agora_sdk/lib/aarch64 -lagora_rtc_sdk
QMAKE_RPATHDIR +=/usr/lib/eswin/aarch64 ../agora_sdk/lib/aarch64
} else {
LIBS += -L/usr/lib/eswin/x86_64 -leswinsdk -L../agora_sdk/lib/x86_64 -lagora_rtc_sdk
QMAKE_RPATHDIR +=/usr/lib/eswin/x86_64 ../agora_sdk/lib/x86_64
}
QMAKE_CXXFLAGS += -DTARGET_OS_LINUX=1 -DLICENSE_CHECK=1 -Wno-sign-compare -Wno-reorder -Wno-unused-variable -Wno-unused-parameter
TRANSLATIONS = AgoraCall_zh_CN.ts
CODECFORSRC = UTF-8
DESTDIR = ../009_QtAgoraCall3 # release 放置的路径
比如我首先尝试一个 QPushButton 的按钮,名为 btnClose,那么,这个事件通知是通过 Sender Slot来进行描述的。
Sender就是这个按钮的名字,是选择的; Signal 是定义用户的行为;Receiver是QT接收到按键之后的行为;Slot()是系统表现出来的。
#include
原来听领导说过,Linux下目前没有类似python parse 的库,直到最近才发现,项目中有同事用到了此类技术,故在这里进行总结,以方便自己下次使用。
示例代码:
...
#include <getopt.h>
...
struct CommandOptions {
eboolean no_preview;
const echar *streamUrl;
const echar *streamName;
euint deviceId;
XXVideoFormat cameraFormat;
euint videoWidth;
euint videoHeight;
euint framerate;
}; // 需要自定义
...
int main(int argc, char *argv[])
{
//... 初始化代码
struct CommandOptions options = {
.no_preview = FALSE,
.streamUrl = "rtmp://xx/live", // live"
.streamName = "myChannel",
.deviceId = 0,
.cameraFormat = xx_VIDEO_FORMAT_UYVY,
.videoWidth = 1920,
.videoHeight = 1080,
.framerate = DEFAULT_FRAME_RATE
};
static struct option long_options[] = {
{ "streamUrl", required_argument, NULL, 'u' },
{ "streamName", required_argument, NULL, 'n' },
{ "deviceId", required_argument, NULL, 'd' },
{ "camfmt", required_argument, NULL, 'f' },
{ "no-preview", no_argument, NULL, 'p' },
{ "width", required_argument, NULL, 'w' },
{ "height", required_argument, NULL, 'h' },
{ "framerate", required_argument, NULL, 'r' },
{ "help", no_argument, NULL, 'H' },
{ 0, 0, 0, 0 }
};
while (TRUE) {
int c;
int option_index = 0;
c = getopt_long(argc, argv, "u:n:d:f:pw:h:r:H", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'u':
options.streamUrl = optarg;
break;
case 'n':
options.streamName = optarg;
break;
case 'd':
options.deviceId = atoi(optarg);
break;
case 'p':
options.no_preview = TRUE;
break;
case 'w':
options.videoWidth = atoi(optarg);
break;
case 'h':
options.videoHeight = atoi(optarg);
break;
case 'r':
options.framerate = atoi(optarg);
break;
case 'H':
print_usage(argv[0]);
exit(0);
break;
case 'f':
options.cameraFormat = xx_get_video_format_from_str(optarg);
if (options.cameraFormat == xx_VIDEO_FORMAT_UNKNOWN){
printf("Unknown video format: %s\n", optarg);
print_usage(argv[0]);
exit(-1);
}
break;
case '?':
print_usage(argv[0]);
exit(-1);
break;
default:
printf("?? getopt returned unknown code 0x%x ??\n", c);
print_usage(argv[0]);
exit(-1);
break;
}
}
if (options.streamUrl == NULL || options.streamName == NULL) {
printf("Stream URL and stream name must be specified!\n");
print_usage(argv[0]);
exit(-1);
}
这里,只有getopt_long是系统调用,需要引入有文件
CS143基础知识; CS243高阶+动手; CS343 读论文
A good place to start is the GCC Wiki Getting Started page: https://gcc.gnu.org/wiki/#Getting_Started_with_GCC_Development
有众多的理由可以让你喜欢编程,那么是什么东西让你坚持这条路的呢?
对于现在我而言,这是一份令我感觉不是那么无聊而且还能领取不错薪水的工作。尽管我向往绝对自由的世界,但是,那种 自由对我来说,太过遥远。
我希望有一天能够: Hack for 纯粹的技术,而不是为了业务而不停的与别人扯皮。
一直都觉得自己在编程方面还是有点欠缺的,也一直鞭策自己不能停下脚本进行学习。
这里,后面还会进行补充。
大家想一想,当你写的代码在遇到一些不明所以的问题时,如何快速的debug呢? GDB是一方面,但是不怎么友好对使用者来说?那还有没有其他的方式呢?
有的,就是log。我们应该把自己写的程序跑过的一些东西,以log的形式保存在 一个特殊的位置,大部分发行版中,大部分位置是 /var/log,也就是如果你确实 找不到一个合适的位置来放置log,那么,这个位置绝对没有问题。
C/C++或者java python等这种强编译型的语言有日志文件比较常见,但是shell也 有log,不知道你之前是否能想到。
下面的代码主要参考这个link。
cat logger.sh
sudo chown $USER:$USER -R /var/log
SCRIPT_LOG=/var/log/SystemOut.log
touch $SCRIPT_LOG
sudo chown $USER:$USER $SCRIPT_LOG
function SCRIPTENTRY(){
timeAndDate=`date`
script_name=`basename "$0"`
script_name="${script_name%.*}"
echo "[$timeAndDate] [DEBUG] > $script_name $FUNCNAME" >> $SCRIPT_LOG
}
function SCRIPTEXIT(){
script_name=`basename "$0"`
script_name="${script_name%.*}"
echo "[$timeAndDate] [DEBUG] < $script_name $FUNCNAME" >> $SCRIPT_LOG
}
function ENTRY(){
local cfn="${FUNCNAME[1]}"
timeAndDate=`date`
echo "[$timeAndDate] [DEBUG] > $cfn $FUNCNAME" >> $SCRIPT_LOG
}
function EXIT(){
local cfn="${FUNCNAME[1]}"
timeAndDate=`date`
echo "[$timeAndDate] [DEBUG] < $cfn $FUNCNAME" >> $SCRIPT_LOG
}
function INFO(){
local function_name="${FUNCNAME[1]}"
local msg="$1"
timeAndDate=`date`
echo "[$timeAndDate] [INFO] $msg" >> $SCRIPT_LOG
}
function DEBUG(){
local function_name="${FUNCNAME[1]}"
local msg="$1"
timeAndDate=`date`
echo "[$timeAndDate] [DEBUG] $msg" >> $SCRIPT_LOG
}
function ERROR(){
local function_name="${FUNCNAME[1]}"
local msg="$1"
timeAndDate=`date`
echo "[$timeAndDate] [ERROR] $msg" >> $SCRIPT_LOG
}
cat test_logger.sh
#!/bin/sh
source ./logger.sh
SCRIPTENTRY
updateUserDetails(){
ENTRY
DEBUG "Username: $1, Key: $2"
INFO "User details updated for $1"
EXIT
}
INFO "Updating user details..."
updateUserDetails "cubicrace" "3445"
rc=2
if [ ! "$rc" = "0" ]
then
ERROR "Failed to update user details. RC=$rc"
fi
SCRIPTEXIT
下面是详细的测试log:
vimer@user-HP:/var/log$ cat SystemOut.log
[2022年 01月 08日 星期六 21:17:23 CST] [DEBUG] > test_logger SCRIPTENTRY
[2022年 01月 08日 星期六 21:17:23 CST] [INFO] Updating user details...
[2022年 01月 08日 星期六 21:17:23 CST] [DEBUG] > updateUserDetails ENTRY
[2022年 01月 08日 星期六 21:17:23 CST] [DEBUG] Username: cubicrace, Key: 3445
[2022年 01月 08日 星期六 21:17:23 CST] [INFO] User details updated for cubicrace
[2022年 01月 08日 星期六 21:17:23 CST] [DEBUG] < updateUserDetails EXIT
[2022年 01月 08日 星期六 21:17:23 CST] [ERROR] Failed to update user details. RC=2
[2022年 01月 08日 星期六 21:17:23 CST] [DEBUG] < test_logger SCRIPTEXIT
[2022年 01月 08日 星期六 21:17:57 CST] [DEBUG] > test_logger SCRIPTENTRY
[2022年 01月 08日 星期六 21:17:57 CST] [INFO] Updating user details...
[2022年 01月 08日 星期六 21:17:57 CST] [DEBUG] > updateUserDetails ENTRY
[2022年 01月 08日 星期六 21:17:57 CST] [DEBUG] Username: cubicrace, Key: 3445
[2022年 01月 08日 星期六 21:17:57 CST] [INFO] User details updated for cubicrace
[2022年 01月 08日 星期六 21:17:57 CST] [DEBUG] < updateUserDetails EXIT
[2022年 01月 08日 星期六 21:17:57 CST] [ERROR] Failed to update user details. RC=2
[2022年 01月 08日 星期六 21:17:57 CST] [DEBUG] < test_logger SCRIPTEXIT
Contains file attributes, metadata of file, pointer structure
Can be considered a table with 2 columns, filename and its inode, inode points to the raw data blocks on the block device
just a special file, container for other filenames. It contains an array of filenames and inode numbers for each filename. Also it describes the relationship between parent and children
On typical ext4 file system (what most people use), the default inode size is 256 bytes, block size is 4096 bytes.
A directory is just a special file which contains an array of filenames and inode numbers. When the directory was created, the file system allocated 1 inode to the directory with a “filename” (dir name in fact). The inode points to a single data block (minimum overhead), which is 4096 bytes. That’s why you see 4096 / 4.0K when using ls.
一个目录仅是一个文件: 包含
You can get the details by using tune2fs & dumpe2fs