mirror of
https://gitee.com/nikolan/keil_development_assistant.git
synced 2025-01-16 07:52:51 +08:00
KDAv1.0 测试版本发布
This commit is contained in:
commit
5599bb19b8
73
.gitignore
vendored
Normal file
73
.gitignore
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
# This file is used to ignore files which are generated
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
*~
|
||||
*.autosave
|
||||
*.a
|
||||
*.core
|
||||
*.moc
|
||||
*.o
|
||||
*.obj
|
||||
*.orig
|
||||
*.rej
|
||||
*.so
|
||||
*.so.*
|
||||
*_pch.h.cpp
|
||||
*_resource.rc
|
||||
*.qm
|
||||
.#*
|
||||
*.*#
|
||||
core
|
||||
!core/
|
||||
tags
|
||||
.DS_Store
|
||||
.directory
|
||||
*.debug
|
||||
Makefile*
|
||||
*.prl
|
||||
*.app
|
||||
moc_*.cpp
|
||||
ui_*.h
|
||||
qrc_*.cpp
|
||||
Thumbs.db
|
||||
*.res
|
||||
*.rc
|
||||
/.qmake.cache
|
||||
/.qmake.stash
|
||||
|
||||
# qtcreator generated files
|
||||
*.pro.user*
|
||||
|
||||
# xemacs temporary files
|
||||
*.flc
|
||||
|
||||
# Vim temporary files
|
||||
.*.swp
|
||||
|
||||
# Visual Studio generated files
|
||||
*.ib_pdb_index
|
||||
*.idb
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.suo
|
||||
*.vcproj
|
||||
*vcproj.*.*.user
|
||||
*.ncb
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.vcxproj
|
||||
*vcxproj.*
|
||||
|
||||
# MinGW generated files
|
||||
*.Debug
|
||||
*.Release
|
||||
|
||||
# Python byte code
|
||||
*.pyc
|
||||
|
||||
# Binaries
|
||||
# --------
|
||||
*.dll
|
||||
*.exe
|
||||
|
BIN
KDA_Logo.ico
Normal file
BIN
KDA_Logo.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 264 KiB |
464
Keil5_disp_size_bar.c
Normal file
464
Keil5_disp_size_bar.c
Normal file
@ -0,0 +1,464 @@
|
||||
#if 0
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define APP_NAME "Keil5_disp_size_bar V0.5"
|
||||
typedef struct mcu_8051_size
|
||||
{
|
||||
uint32_t iram_size;
|
||||
uint32_t xram_size;
|
||||
uint32_t irom_size;
|
||||
uint32_t iram_max;
|
||||
uint32_t xram_max;
|
||||
uint32_t irom_max;
|
||||
} mcu_8051_size_t;
|
||||
mcu_8051_size_t mcu_8051 = {0};
|
||||
|
||||
void print_msg(const char *tag, const char *format, ...);
|
||||
FILE *find_file_in_dir_by_name(const char *dir_name, const char *file_name);
|
||||
int64_t file_sreach_string_get_pos(FILE *fp, char *sub_str, int seek, uint32_t offset);
|
||||
void prtint_percentage_bar(char *label, uint8_t cnt, uint32_t val, uint32_t max);
|
||||
uint32_t str_get_hex(char *str, char *str_hex);
|
||||
void process_execution_region(FILE *fp_map);
|
||||
float str_get_dec(char *str, char *str_dec);
|
||||
uint8_t find_8051(void);
|
||||
void find_project_size_define(void);
|
||||
|
||||
uint32_t ram_max_from_porject = 0;
|
||||
uint32_t rom_max_from_porject = 0;
|
||||
|
||||
// argv[0] 是当前exe文件的路径
|
||||
// exe放在工程文件的同一目录下就可以获取到工程目录了
|
||||
int main2(int argc, char *argv[])
|
||||
{
|
||||
DIR *dir;
|
||||
char *path = NULL;
|
||||
FILE *fp_map;
|
||||
// 打开当前目录
|
||||
int64_t pos = 0;
|
||||
|
||||
if (find_8051())
|
||||
return;
|
||||
|
||||
find_project_size_define();
|
||||
|
||||
print_msg(APP_NAME, "find map file start");
|
||||
fp_map = find_file_in_dir_by_name("./", ".map");
|
||||
|
||||
process_execution_region(fp_map);
|
||||
|
||||
fclose(fp_map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_msg(const char *tag, const char *format, ...)
|
||||
{
|
||||
printf("[%s]: ", tag);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
FILE *find_file_in_dir_by_name(const char *dir_name, const char *file_name)
|
||||
{
|
||||
FILE *fp;
|
||||
DIR *dir;
|
||||
struct dirent *st;
|
||||
struct stat sta;
|
||||
|
||||
int ret = 0;
|
||||
char tmp_name[1024] = {0};
|
||||
|
||||
if ((dir = opendir(dir_name)) == NULL)
|
||||
{
|
||||
printf("%s: Open dir error\n", APP_NAME);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ((st = readdir(dir)) != NULL)
|
||||
{
|
||||
strcpy(tmp_name, dir_name);
|
||||
strcat(tmp_name, "/");
|
||||
strcat(tmp_name, st->d_name); // 新文件路径名
|
||||
|
||||
ret = stat(tmp_name, &sta); // 查看目录下文件属性
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
print_msg(APP_NAME "Read stat failed for %s", tmp_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (S_ISDIR(sta.st_mode))
|
||||
{ // 如果为目录文件
|
||||
if (strcmp("..", st->d_name) == 0 || strcmp(".", st->d_name) == 0)
|
||||
{
|
||||
continue; // 忽略当前目录和上一层目录
|
||||
}
|
||||
else
|
||||
{
|
||||
fp = find_file_in_dir_by_name(tmp_name, file_name); // 递归读取
|
||||
if (fp)
|
||||
{
|
||||
closedir(dir);
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // 不为目录则打印文件路径名
|
||||
if (strstr(tmp_name, file_name))
|
||||
{
|
||||
fp = fopen(tmp_name, "r+");
|
||||
if (!fp)
|
||||
{
|
||||
// print_msg(APP_NAME, "Failed to open file: %s", tmp_name);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
print_msg(APP_NAME, "Found file: %s", tmp_name);
|
||||
closedir(dir);
|
||||
return fp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int64_t file_sreach_string_get_pos(FILE *fp, char *sub_str, int seek, uint32_t offset)
|
||||
{
|
||||
char str[1000];
|
||||
int64_t pos = 0;
|
||||
fseek(fp, offset, seek);
|
||||
|
||||
while (NULL != fgets(str, 1000, fp))
|
||||
{
|
||||
|
||||
if (strstr(str, sub_str))
|
||||
{
|
||||
|
||||
// printf("%s", str);
|
||||
pos = ftell(fp) - strlen(str);
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void prtint_percentage_bar(char *label, uint8_t cnt, uint32_t val, uint32_t max)
|
||||
{
|
||||
uint8_t i;
|
||||
printf("%5d KB %5s%u:|", (uint32_t)(max / 1024.0f), label, cnt);
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
if (i < (uint8_t)((val / 1.0) / (max / 1.0) * 20))
|
||||
{
|
||||
|
||||
printf("■");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("_");
|
||||
}
|
||||
}
|
||||
printf("|%6.2f %% (%8.2f KB / %8.2f KB)", (val / 1.0) / (max / 1.0) * 100, val / 1024.0f, max / 1024.0f);
|
||||
printf(" [%u B]\n", max - val);
|
||||
}
|
||||
|
||||
uint32_t str_get_hex(char *str, char *str_hex)
|
||||
{
|
||||
|
||||
char *str_buf;
|
||||
uint32_t hex;
|
||||
|
||||
str_buf = strstr(str, str_hex);
|
||||
if (str_buf == NULL)
|
||||
return 0;
|
||||
str_buf += strlen(str_hex);
|
||||
sscanf(str_buf, "%x", &hex);
|
||||
|
||||
// printf("%s:%#x\n", str_hex,hex);
|
||||
|
||||
return hex;
|
||||
}
|
||||
|
||||
float str_get_dec(char *str, char *str_dec)
|
||||
{
|
||||
|
||||
char *str_buf;
|
||||
float dec;
|
||||
|
||||
str_buf = strstr(str, str_dec);
|
||||
if (str_buf == NULL)
|
||||
return 0;
|
||||
str_buf += strlen(str_dec);
|
||||
sscanf(str_buf, "%f", &dec);
|
||||
|
||||
// printf("%s:%#x\n", str_hex,hex);
|
||||
|
||||
return dec;
|
||||
}
|
||||
|
||||
void process_execution_region(FILE *fp_map)
|
||||
{
|
||||
|
||||
int64_t pos = 0;
|
||||
char str[1000];
|
||||
char *ch_p = NULL;
|
||||
uint32_t exec_base = 0, load_base = 0, size = 0, max = 0;
|
||||
uint8_t ram_cnt = 0, flash_cnt = 0;
|
||||
|
||||
uint8_t cnt = 0;
|
||||
uint32_t ram_size[30];
|
||||
uint32_t flash_size[30];
|
||||
|
||||
uint32_t ram_max[30];
|
||||
uint32_t flash_max[30];
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
pos = file_sreach_string_get_pos(fp_map, "Execution Region", SEEK_SET, pos);
|
||||
if (-1 == pos)
|
||||
{
|
||||
print_msg(APP_NAME, "map file read end\n");
|
||||
break;
|
||||
}
|
||||
|
||||
fseek(fp_map, pos, SEEK_SET);
|
||||
fgets(str, 1000, fp_map);
|
||||
|
||||
if (strstr(str, "RAM"))
|
||||
{
|
||||
|
||||
ram_size[ram_cnt] = str_get_hex(str, "Size: ");
|
||||
pos += strstr(str, "Size: ") - str;
|
||||
fseek(fp_map, pos, SEEK_SET);
|
||||
|
||||
ram_max[ram_cnt] = str_get_hex(str, "Max: ");
|
||||
if (ram_max[ram_cnt] > 100 * 1024 * 1024)
|
||||
ram_max[ram_cnt] = ram_max_from_porject;
|
||||
|
||||
pos += strstr(str, "Max: ") - str;
|
||||
fseek(fp_map, pos, SEEK_SET);
|
||||
if (ram_cnt < 30)
|
||||
ram_cnt++;
|
||||
// prtint_percentage_bar("ram",ram_cnt, size, max);
|
||||
}
|
||||
else if (strstr(str, "ER$$") ||strstr(str, "RW_")|| strstr(str, "ER_RW") || strstr(str, "ER_ZI"))
|
||||
{
|
||||
|
||||
ram_size[ram_cnt] = str_get_hex(str, "Size: ");
|
||||
pos += strstr(str, "Size: ") - str;
|
||||
fseek(fp_map, pos, SEEK_SET);
|
||||
|
||||
ram_max[ram_cnt] = str_get_hex(str, "Max: ");
|
||||
if (ram_max[ram_cnt] > 100 * 1024 * 1024)
|
||||
ram_max[ram_cnt] = ram_max_from_porject;
|
||||
print_msg(APP_NAME,"RAMMAX:%d\n",ram_max[ram_cnt]);
|
||||
|
||||
pos += strstr(str, "Max: ") - str;
|
||||
fseek(fp_map, pos, SEEK_SET);
|
||||
if (ram_cnt < 30)
|
||||
ram_cnt++;
|
||||
// prtint_percentage_bar("ram",ram_cnt, size, max);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
flash_size[flash_cnt] = str_get_hex(str, "Size: ");
|
||||
pos += strstr(str, "Size: ") - str;
|
||||
fseek(fp_map, pos, SEEK_SET);
|
||||
|
||||
flash_max[flash_cnt] = str_get_hex(str, "Max: ");
|
||||
if (flash_max[flash_cnt] > 100 * 1024 * 1024)
|
||||
flash_max[flash_cnt] = rom_max_from_porject;
|
||||
|
||||
pos += strstr(str, "Max: ") - str;
|
||||
fseek(fp_map, pos, SEEK_SET);
|
||||
if (flash_cnt < 30)
|
||||
flash_cnt++;
|
||||
// prtint_percentage_bar("flash",flash_cnt, size, max);
|
||||
}
|
||||
}
|
||||
|
||||
printf("ram:\n");
|
||||
for (cnt = 0; cnt < ram_cnt; cnt++)
|
||||
{
|
||||
prtint_percentage_bar("ram", cnt + 1, ram_size[cnt], ram_max[cnt]);
|
||||
}
|
||||
printf("flash:\n");
|
||||
for (cnt = 0; cnt < flash_cnt; cnt++)
|
||||
{
|
||||
prtint_percentage_bar("flash", cnt + 1, flash_size[cnt], flash_max[cnt]);
|
||||
}
|
||||
|
||||
printf(" \n");
|
||||
}
|
||||
|
||||
uint8_t find_8051(void)
|
||||
{
|
||||
FILE *fp_project=NULL;
|
||||
FILE *fp_m51=NULL;
|
||||
int64_t pos = 0;
|
||||
char str[1000];
|
||||
|
||||
uint8_t cnt = 0;
|
||||
|
||||
print_msg(APP_NAME, "find project satrt!");
|
||||
fp_project = find_file_in_dir_by_name("./", ".uvproj");
|
||||
if (fp_project == NULL)
|
||||
{
|
||||
print_msg(APP_NAME, "find project fail!");
|
||||
fp_project = find_file_in_dir_by_name("./", ".uvprojx");
|
||||
if (fp_project == NULL)
|
||||
{
|
||||
print_msg(APP_NAME, "find project fail!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
pos = file_sreach_string_get_pos(fp_project, "<Cpu>", SEEK_SET, pos);
|
||||
if (-1 == pos)
|
||||
{
|
||||
print_msg(APP_NAME, "found cup info fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(fp_project, pos - 8, SEEK_SET);
|
||||
fgets(str, 1000, fp_project);
|
||||
if (strstr(str, "IRAM(0-"))
|
||||
{
|
||||
|
||||
print_msg(APP_NAME, "cup is 8051\n");
|
||||
|
||||
mcu_8051.iram_max = str_get_hex(str, "IRAM(0-");
|
||||
|
||||
if(strstr(str, "XRAM(0-"))
|
||||
mcu_8051.xram_max = str_get_hex(str, "XRAM(0-");
|
||||
else
|
||||
mcu_8051.xram_max = mcu_8051.iram_max;
|
||||
|
||||
mcu_8051.irom_max = str_get_hex(str, "IROM(0-");
|
||||
// printf("iram_max:%d,xram_max:%d,irom_max:%d\n",mcu_8051.iram_max,mcu_8051.xram_max,mcu_8051.irom_max);
|
||||
fclose(fp_project); // 关闭文件
|
||||
fp_m51 = find_file_in_dir_by_name("./", ".m51");
|
||||
pos = file_sreach_string_get_pos(fp_m51, "Program Size:", SEEK_SET, pos);
|
||||
fgets(str, 1000, fp_project);
|
||||
mcu_8051.iram_size = str_get_dec(str, "data=");
|
||||
|
||||
|
||||
|
||||
mcu_8051.irom_size = str_get_dec(str, "code=");
|
||||
// printf("iram_size:%d,xram_size:%d,irom_size:%d\n",mcu_8051.iram_size,mcu_8051.xram_size,mcu_8051.irom_size);
|
||||
|
||||
prtint_percentage_bar("flash", 1, mcu_8051.irom_size, mcu_8051.irom_max);
|
||||
prtint_percentage_bar("iram", 1, mcu_8051.iram_size, mcu_8051.iram_max);
|
||||
|
||||
if(strstr(str, "xdata="))
|
||||
{
|
||||
mcu_8051.xram_size = str_get_dec(str, "xdata=");
|
||||
prtint_percentage_bar("xram", 1, mcu_8051.xram_size, mcu_8051.xram_max);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void find_project_size_define(void)
|
||||
{
|
||||
|
||||
FILE *fp_project=NULL;
|
||||
int64_t pos = 0;
|
||||
char str[1000];
|
||||
char *ch_p = NULL;
|
||||
|
||||
// print_msg(APP_NAME, "find project satrt!");
|
||||
fp_project = find_file_in_dir_by_name("./", ".uvproj");
|
||||
if (fp_project == NULL)
|
||||
{
|
||||
fp_project = find_file_in_dir_by_name("./", ".uvprojx");
|
||||
if (fp_project == NULL)
|
||||
{
|
||||
// print_msg(APP_NAME, "find project fail!");
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
pos = file_sreach_string_get_pos(fp_project, "<Cpu>", SEEK_SET, pos);
|
||||
if (-1 == pos)
|
||||
{
|
||||
print_msg(APP_NAME, "found cup info fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(fp_project, pos - 8, SEEK_SET);
|
||||
fgets(str, 1000, fp_project);
|
||||
if (ch_p = strstr(str, "IRAM("))
|
||||
{
|
||||
if(strstr(ch_p, ","))
|
||||
{
|
||||
ram_max_from_porject = str_get_hex(ch_p, ",");
|
||||
ch_p = strstr(ch_p, ",");
|
||||
ch_p++;
|
||||
rom_max_from_porject = str_get_hex(ch_p, ",");
|
||||
}
|
||||
else if(strstr(ch_p, "-"))
|
||||
{
|
||||
ram_max_from_porject = str_get_hex(ch_p, "-");
|
||||
ch_p = strstr(ch_p, "-");
|
||||
ch_p++;
|
||||
rom_max_from_porject = str_get_hex(ch_p, "-");
|
||||
}
|
||||
// print_msg(APP_NAME,"IARM:%d,IROM:%d\n",ram_max_from_porject,rom_max_from_porject);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fclose(fp_project); // 关闭文件
|
||||
|
||||
}
|
||||
#endif
|
6
R.qrc
Normal file
6
R.qrc
Normal file
@ -0,0 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>KDA_Logo.ico</file>
|
||||
<file>gitee.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
40
find_path.cpp
Normal file
40
find_path.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "find_path.h"
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include <QDomDocument>
|
||||
#include <QFileInfoList>
|
||||
#include <QDir>
|
||||
|
||||
find_path::find_path()
|
||||
{
|
||||
|
||||
}
|
||||
QString find_path::find_file_path(const QString& dir_path,const QString& key_world)
|
||||
{
|
||||
QFileInfoList fileInfoList;
|
||||
QString file_path="";
|
||||
QDir dir(dir_path);
|
||||
foreach(QFileInfo info,dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs)){
|
||||
|
||||
// qDebug()<<"dir:"<<info.filePath();
|
||||
|
||||
file_path=find_file_path(info.filePath(),key_world);
|
||||
if(file_path!="")
|
||||
return file_path;
|
||||
|
||||
}
|
||||
|
||||
foreach(QFileInfo info,dir.entryInfoList(QDir::Files)){
|
||||
fileInfoList.append(info);
|
||||
if(info.fileName().contains(key_world))
|
||||
{
|
||||
|
||||
|
||||
file_path=info.path()+"/"+info.fileName();
|
||||
// qDebug()<<info.path()+"/"+info.fileName();
|
||||
return file_path;
|
||||
}
|
||||
|
||||
}
|
||||
return file_path;
|
||||
}
|
13
find_path.h
Normal file
13
find_path.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef FIND_PATH_H
|
||||
#define FIND_PATH_H
|
||||
|
||||
#include <QString>
|
||||
class find_path
|
||||
{
|
||||
public:
|
||||
find_path();
|
||||
static QString find_file_path(const QString& dir_path,const QString& key_world);
|
||||
|
||||
};
|
||||
|
||||
#endif // FIND_PATH_H
|
170
flatui.cpp
Normal file
170
flatui.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "flatui.h"
|
||||
#include "qpushbutton.h"
|
||||
#include "qlineedit.h"
|
||||
#include "qprogressbar.h"
|
||||
#include "qslider.h"
|
||||
#include "qradiobutton.h"
|
||||
#include "qcheckbox.h"
|
||||
#include "qscrollbar.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
QString FlatUI::setPushButtonQss(QPushButton *btn, int radius, int padding,
|
||||
const QString &normalColor,
|
||||
const QString &normalTextColor,
|
||||
const QString &hoverColor,
|
||||
const QString &hoverTextColor,
|
||||
const QString &pressedColor,
|
||||
const QString &pressedTextColor)
|
||||
{
|
||||
QStringList list;
|
||||
list.append(QString("QPushButton{border-style:none;padding:%1px;border-radius:%2px;color:%3;background:%4;}")
|
||||
.arg(padding).arg(radius).arg(normalTextColor).arg(normalColor));
|
||||
list.append(QString("QPushButton:hover{color:%1;background:%2;}")
|
||||
.arg(hoverTextColor).arg(hoverColor));
|
||||
list.append(QString("QPushButton:pressed{color:%1;background:%2;}")
|
||||
.arg(pressedTextColor).arg(pressedColor));
|
||||
|
||||
QString qss = list.join("");
|
||||
btn->setStyleSheet(qss);
|
||||
return qss;
|
||||
}
|
||||
|
||||
QString FlatUI::setLineEditQss(QLineEdit *txt, int radius, int borderWidth,
|
||||
const QString &normalColor,
|
||||
const QString &focusColor)
|
||||
{
|
||||
QStringList list;
|
||||
list.append(QString("QLineEdit{border-style:none;padding:3px;border-radius:%1px;border:%2px solid %3;}")
|
||||
.arg(radius).arg(borderWidth).arg(normalColor));
|
||||
list.append(QString("QLineEdit:focus{border:%1px solid %2;}")
|
||||
.arg(borderWidth).arg(focusColor));
|
||||
|
||||
QString qss = list.join("");
|
||||
txt->setStyleSheet(qss);
|
||||
return qss;
|
||||
}
|
||||
|
||||
QString FlatUI::setProgressQss(QProgressBar *bar, int barHeight,
|
||||
int barRadius, int fontSize,
|
||||
const QString &normalColor,
|
||||
const QString &chunkColor)
|
||||
{
|
||||
|
||||
QStringList list;
|
||||
list.append(QString("QProgressBar{color:#FFFFFF;font:%1px;background:%2;max-height:%3px;border-radius:%4px;text-align:center;border:1px solid %2;}")
|
||||
.arg(fontSize).arg(normalColor).arg(barHeight).arg(barRadius));
|
||||
list.append(QString("QProgressBar:chunk{border-radius:%2px;background-color:%1;}")
|
||||
.arg(chunkColor).arg(barRadius));
|
||||
|
||||
QString qss = list.join("");
|
||||
bar->setStyleSheet(qss);
|
||||
return qss;
|
||||
}
|
||||
|
||||
QString FlatUI::setSliderQss(QSlider *slider, int sliderHeight,
|
||||
const QString &normalColor,
|
||||
const QString &grooveColor,
|
||||
const QString &handleBorderColor,
|
||||
const QString &handleColor)
|
||||
{
|
||||
int sliderRadius = sliderHeight / 2;
|
||||
int handleWidth = (sliderHeight * 3) / 2 + (sliderHeight / 5);
|
||||
int handleRadius = handleWidth / 2;
|
||||
int handleOffset = handleRadius / 2;
|
||||
|
||||
QStringList list;
|
||||
list.append(QString("QSlider::horizontal{min-height:%1px;}").arg(sliderHeight * 2));
|
||||
list.append(QString("QSlider::groove:horizontal{background:%1;height:%2px;border-radius:%3px;}")
|
||||
.arg(normalColor).arg(sliderHeight).arg(sliderRadius));
|
||||
list.append(QString("QSlider::add-page:horizontal{background:%1;height:%2px;border-radius:%3px;}")
|
||||
.arg(normalColor).arg(sliderHeight).arg(sliderRadius));
|
||||
list.append(QString("QSlider::sub-page:horizontal{background:%1;height:%2px;border-radius:%3px;}")
|
||||
.arg(grooveColor).arg(sliderHeight).arg(sliderRadius));
|
||||
list.append(QString("QSlider::handle:horizontal{width:%3px;margin-top:-%4px;margin-bottom:-%4px;border-radius:%5px;"
|
||||
"background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.6 %1,stop:0.8 %2);}")
|
||||
.arg(handleColor).arg(handleBorderColor).arg(handleWidth).arg(handleOffset).arg(handleRadius));
|
||||
|
||||
//偏移一个像素
|
||||
handleWidth = handleWidth + 1;
|
||||
list.append(QString("QSlider::vertical{min-width:%1px;}").arg(sliderHeight * 2));
|
||||
list.append(QString("QSlider::groove:vertical{background:%1;width:%2px;border-radius:%3px;}")
|
||||
.arg(normalColor).arg(sliderHeight).arg(sliderRadius));
|
||||
list.append(QString("QSlider::add-page:vertical{background:%1;width:%2px;border-radius:%3px;}")
|
||||
.arg(grooveColor).arg(sliderHeight).arg(sliderRadius));
|
||||
list.append(QString("QSlider::sub-page:vertical{background:%1;width:%2px;border-radius:%3px;}")
|
||||
.arg(normalColor).arg(sliderHeight).arg(sliderRadius));
|
||||
list.append(QString("QSlider::handle:vertical{height:%3px;margin-left:-%4px;margin-right:-%4px;border-radius:%5px;"
|
||||
"background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.6 %1,stop:0.8 %2);}")
|
||||
.arg(handleColor).arg(handleBorderColor).arg(handleWidth).arg(handleOffset).arg(handleRadius));
|
||||
|
||||
QString qss = list.join("");
|
||||
slider->setStyleSheet(qss);
|
||||
return qss;
|
||||
}
|
||||
|
||||
QString FlatUI::setRadioButtonQss(QRadioButton *rbtn, int indicatorRadius,
|
||||
const QString &normalColor,
|
||||
const QString &checkColor)
|
||||
{
|
||||
int indicatorWidth = indicatorRadius * 2;
|
||||
|
||||
QStringList list;
|
||||
list.append(QString("QRadioButton::indicator{border-radius:%1px;width:%2px;height:%2px;}")
|
||||
.arg(indicatorRadius).arg(indicatorWidth));
|
||||
list.append(QString("QRadioButton::indicator::unchecked{background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,"
|
||||
"stop:0.6 #FFFFFF,stop:0.7 %1);}").arg(normalColor));
|
||||
list.append(QString("QRadioButton::indicator::checked{background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,"
|
||||
"stop:0 %1,stop:0.3 %1,stop:0.4 #FFFFFF,stop:0.6 #FFFFFF,stop:0.7 %1);}").arg(checkColor));
|
||||
|
||||
QString qss = list.join("");
|
||||
rbtn->setStyleSheet(qss);
|
||||
return qss;
|
||||
}
|
||||
|
||||
QString FlatUI::setScrollBarQss(QWidget *scroll, int radius, int min, int max,
|
||||
const QString &bgColor,
|
||||
const QString &handleNormalColor,
|
||||
const QString &handleHoverColor,
|
||||
const QString &handlePressedColor)
|
||||
{
|
||||
//滚动条离背景间隔
|
||||
int padding = 0;
|
||||
|
||||
QStringList list;
|
||||
|
||||
//handle:指示器,滚动条拉动部分 add-page:滚动条拉动时增加的部分 sub-page:滚动条拉动时减少的部分 add-line:递增按钮 sub-line:递减按钮
|
||||
|
||||
//横向滚动条部分
|
||||
list.append(QString("QScrollBar:horizontal{background:%1;padding:%2px;border-radius:%3px;min-height:%4px;max-height:%4px;}")
|
||||
.arg(bgColor).arg(padding).arg(radius).arg(max));
|
||||
list.append(QString("QScrollBar::handle:horizontal{background:%1;min-width:%2px;border-radius:%3px;}")
|
||||
.arg(handleNormalColor).arg(min).arg(radius));
|
||||
list.append(QString("QScrollBar::handle:horizontal:hover{background:%1;}")
|
||||
.arg(handleHoverColor));
|
||||
list.append(QString("QScrollBar::handle:horizontal:pressed{background:%1;}")
|
||||
.arg(handlePressedColor));
|
||||
list.append(QString("QScrollBar::add-page:horizontal{background:none;}"));
|
||||
list.append(QString("QScrollBar::sub-page:horizontal{background:none;}"));
|
||||
list.append(QString("QScrollBar::add-line:horizontal{background:none;}"));
|
||||
list.append(QString("QScrollBar::sub-line:horizontal{background:none;}"));
|
||||
|
||||
//纵向滚动条部分
|
||||
list.append(QString("QScrollBar:vertical{background:%1;padding:%2px;border-radius:%3px;min-width:%4px;max-width:%4px;}")
|
||||
.arg(bgColor).arg(padding).arg(radius).arg(max));
|
||||
list.append(QString("QScrollBar::handle:vertical{background:%1;min-height:%2px;border-radius:%3px;}")
|
||||
.arg(handleNormalColor).arg(min).arg(radius));
|
||||
list.append(QString("QScrollBar::handle:vertical:hover{background:%1;}")
|
||||
.arg(handleHoverColor));
|
||||
list.append(QString("QScrollBar::handle:vertical:pressed{background:%1;}")
|
||||
.arg(handlePressedColor));
|
||||
list.append(QString("QScrollBar::add-page:vertical{background:none;}"));
|
||||
list.append(QString("QScrollBar::sub-page:vertical{background:none;}"));
|
||||
list.append(QString("QScrollBar::add-line:vertical{background:none;}"));
|
||||
list.append(QString("QScrollBar::sub-line:vertical{background:none;}"));
|
||||
|
||||
QString qss = list.join("");
|
||||
scroll->setStyleSheet(qss);
|
||||
return qss;
|
||||
}
|
85
flatui.h
Normal file
85
flatui.h
Normal file
@ -0,0 +1,85 @@
|
||||
#ifndef FLATUI_H
|
||||
#define FLATUI_H
|
||||
|
||||
/**
|
||||
* FlatUI辅助类 作者:feiyangqingyun(QQ:517216493) 2016-12-16
|
||||
* 1. 按钮样式设置。
|
||||
* 2. 文本框样式设置。
|
||||
* 3. 进度条样式。
|
||||
* 4. 滑块条样式。
|
||||
* 5. 单选框样式。
|
||||
* 6. 滚动条样式。
|
||||
* 7. 可自由设置对象的高度宽度大小等。
|
||||
* 8. 自带默认参数值。
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QPushButton;
|
||||
class QLineEdit;
|
||||
class QProgressBar;
|
||||
class QSlider;
|
||||
class QRadioButton;
|
||||
class QCheckBox;
|
||||
class QScrollBar;
|
||||
|
||||
#ifdef quc
|
||||
class Q_DECL_EXPORT FlatUI
|
||||
#else
|
||||
class FlatUI
|
||||
#endif
|
||||
|
||||
{
|
||||
public:
|
||||
//设置按钮样式
|
||||
static QString setPushButtonQss(QPushButton *btn, //按钮对象
|
||||
int radius = 5, //圆角半径
|
||||
int padding = 8, //间距
|
||||
const QString &normalColor = "#34495E", //正常颜色
|
||||
const QString &normalTextColor = "#FFFFFF", //文字颜色
|
||||
const QString &hoverColor = "#4E6D8C", //悬停颜色
|
||||
const QString &hoverTextColor = "#F0F0F0", //悬停文字颜色
|
||||
const QString &pressedColor = "#2D3E50", //按下颜色
|
||||
const QString &pressedTextColor = "#B8C6D1"); //按下文字颜色
|
||||
|
||||
//设置文本框样式
|
||||
static QString setLineEditQss(QLineEdit *txt, //文本框对象
|
||||
int radius = 3, //圆角半径
|
||||
int borderWidth = 2, //边框大小
|
||||
const QString &normalColor = "#DCE4EC", //正常颜色
|
||||
const QString &focusColor = "#34495E"); //选中颜色
|
||||
|
||||
//设置进度条样式
|
||||
static QString setProgressQss(QProgressBar *bar,
|
||||
int barHeight = 8, //进度条高度
|
||||
int barRadius = 5, //进度条半径
|
||||
int fontSize = 12, //文字字号
|
||||
const QString &normalColor = "#E8EDF2", //正常颜色
|
||||
const QString &chunkColor = "#E74C3C"); //进度颜色
|
||||
|
||||
//设置滑块条样式
|
||||
static QString setSliderQss(QSlider *slider, //滑动条对象
|
||||
int sliderHeight = 8, //滑动条高度
|
||||
const QString &normalColor = "#E8EDF2", //正常颜色
|
||||
const QString &grooveColor = "#1ABC9C", //滑块颜色
|
||||
const QString &handleBorderColor = "#1ABC9C", //指示器边框颜色
|
||||
const QString &handleColor = "#FFFFFF"); //指示器颜色
|
||||
|
||||
//设置单选框样式
|
||||
static QString setRadioButtonQss(QRadioButton *rbtn, //单选框对象
|
||||
int indicatorRadius = 8, //指示器圆角角度
|
||||
const QString &normalColor = "#D7DBDE", //正常颜色
|
||||
const QString &checkColor = "#34495E"); //选中颜色
|
||||
|
||||
//设置滚动条样式
|
||||
static QString setScrollBarQss(QWidget *scroll, //滚动条对象
|
||||
int radius = 6, //圆角角度
|
||||
int min = 120, //指示器最小长度
|
||||
int max = 12, //滚动条最大长度
|
||||
const QString &bgColor = "#606060", //背景色
|
||||
const QString &handleNormalColor = "#34495E", //指示器正常颜色
|
||||
const QString &handleHoverColor = "#1ABC9C", //指示器悬停颜色
|
||||
const QString &handlePressedColor = "#E74C3C"); //指示器按下颜色
|
||||
};
|
||||
|
||||
#endif // FLATUI_H
|
9
framelesscore/framelesscore.pri
Normal file
9
framelesscore/framelesscore.pri
Normal file
@ -0,0 +1,9 @@
|
||||
HEADERS += \
|
||||
$$PWD/framelessdialog.h \
|
||||
$$PWD/framelessmainwindow.h \
|
||||
$$PWD/framelesswidget.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/framelessdialog.cpp \
|
||||
$$PWD/framelessmainwindow.cpp \
|
||||
$$PWD/framelesswidget.cpp
|
377
framelesscore/framelessdialog.cpp
Normal file
377
framelesscore/framelessdialog.cpp
Normal file
@ -0,0 +1,377 @@
|
||||
#include "framelessdialog.h"
|
||||
#include "qdatetime.h"
|
||||
#include "qevent.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "windows.h"
|
||||
#include "windowsx.h"
|
||||
#pragma comment (lib,"user32.lib")
|
||||
#endif
|
||||
|
||||
#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
|
||||
|
||||
FramelessDialog::FramelessDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
padding = 8;
|
||||
moveEnable = true;
|
||||
resizeEnable = true;
|
||||
|
||||
mousePressed = false;
|
||||
mousePoint = QPoint(0, 0);
|
||||
mouseRect = QRect(0, 0, 0, 0);
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
pressedArea << false;
|
||||
pressedRect << QRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
isMin = false;
|
||||
flags = this->windowFlags();
|
||||
titleBar = 0;
|
||||
|
||||
//设置背景透明 官方在5.3以后才彻底修复 WA_TranslucentBackground+FramelessWindowHint 并存不绘制的bug
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,3,0))
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
#endif
|
||||
//设置无边框属性
|
||||
this->setWindowFlags(flags | Qt::FramelessWindowHint);
|
||||
//安装事件过滤器识别拖动
|
||||
this->installEventFilter(this);
|
||||
|
||||
//设置属性产生win窗体效果,移动到边缘半屏或者最大化等
|
||||
//设置以后会产生标题栏需要在下面拦截消息重新去掉
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = (HWND)this->winId();
|
||||
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
|
||||
::SetWindowLong(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessDialog::showEvent(QShowEvent *event)
|
||||
{
|
||||
//解决有时候窗体重新显示的时候假死不刷新的bug
|
||||
setAttribute(Qt::WA_Mapped);
|
||||
QDialog::showEvent(event);
|
||||
}
|
||||
|
||||
void FramelessDialog::doWindowStateChange(QEvent *event)
|
||||
{
|
||||
//非最大化才能移动和拖动大小
|
||||
if (windowState() == Qt::WindowNoState) {
|
||||
moveEnable = true;
|
||||
resizeEnable = true;
|
||||
} else {
|
||||
moveEnable = false;
|
||||
resizeEnable = false;
|
||||
}
|
||||
|
||||
//发出最大化最小化等改变事件,以便界面上更改对应的信息比如右上角图标和文字
|
||||
emit windowStateChange(!moveEnable);
|
||||
|
||||
//解决mac系统上无边框最小化失效的bug
|
||||
#ifdef Q_OS_MACOS
|
||||
if (windowState() & Qt::WindowMinimized) {
|
||||
isMin = true;
|
||||
} else {
|
||||
if (isMin) {
|
||||
//设置无边框属性
|
||||
this->setWindowFlags(flags | Qt::FramelessWindowHint);
|
||||
this->setVisible(true);
|
||||
isMin = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessDialog::doResizeEvent(QEvent *event)
|
||||
{
|
||||
//非win系统的无边框拉伸,win系统上已经采用了nativeEvent来处理拉伸
|
||||
//为何不统一用计算的方式因为在win上用这个方式往左拉伸会发抖妹的
|
||||
#ifndef Q_OS_WIN
|
||||
if (event->type() == QEvent::Resize) {
|
||||
//重新计算八个描点的区域,描点区域的作用还有就是计算鼠标坐标是否在某一个区域内
|
||||
int width = this->width();
|
||||
int height = this->height();
|
||||
|
||||
//左侧描点区域
|
||||
pressedRect[0] = QRect(0, padding, padding, height - padding * 2);
|
||||
//右侧描点区域
|
||||
pressedRect[1] = QRect(width - padding, padding, padding, height - padding * 2);
|
||||
//上侧描点区域
|
||||
pressedRect[2] = QRect(padding, 0, width - padding * 2, padding);
|
||||
//下侧描点区域
|
||||
pressedRect[3] = QRect(padding, height - padding, width - padding * 2, padding);
|
||||
|
||||
//左上角描点区域
|
||||
pressedRect[4] = QRect(0, 0, padding, padding);
|
||||
//右上角描点区域
|
||||
pressedRect[5] = QRect(width - padding, 0, padding, padding);
|
||||
//左下角描点区域
|
||||
pressedRect[6] = QRect(0, height - padding, padding, padding);
|
||||
//右下角描点区域
|
||||
pressedRect[7] = QRect(width - padding, height - padding, padding, padding);
|
||||
} else if (event->type() == QEvent::HoverMove) {
|
||||
//设置对应鼠标形状,这个必须放在这里而不是下面,因为可以在鼠标没有按下的时候识别
|
||||
QHoverEvent *hoverEvent = (QHoverEvent *)event;
|
||||
QPoint point = hoverEvent->pos();
|
||||
if (resizeEnable) {
|
||||
if (pressedRect.at(0).contains(point)) {
|
||||
this->setCursor(Qt::SizeHorCursor);
|
||||
} else if (pressedRect.at(1).contains(point)) {
|
||||
this->setCursor(Qt::SizeHorCursor);
|
||||
} else if (pressedRect.at(2).contains(point)) {
|
||||
this->setCursor(Qt::SizeVerCursor);
|
||||
} else if (pressedRect.at(3).contains(point)) {
|
||||
this->setCursor(Qt::SizeVerCursor);
|
||||
} else if (pressedRect.at(4).contains(point)) {
|
||||
this->setCursor(Qt::SizeFDiagCursor);
|
||||
} else if (pressedRect.at(5).contains(point)) {
|
||||
this->setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (pressedRect.at(6).contains(point)) {
|
||||
this->setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (pressedRect.at(7).contains(point)) {
|
||||
this->setCursor(Qt::SizeFDiagCursor);
|
||||
} else {
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
}
|
||||
|
||||
//根据当前鼠标位置,计算XY轴移动了多少
|
||||
int offsetX = point.x() - mousePoint.x();
|
||||
int offsetY = point.y() - mousePoint.y();
|
||||
|
||||
//根据按下处的位置判断是否是移动控件还是拉伸控件
|
||||
if (moveEnable && mousePressed) {
|
||||
this->move(this->x() + offsetX, this->y() + offsetY);
|
||||
}
|
||||
|
||||
if (resizeEnable) {
|
||||
int rectX = mouseRect.x();
|
||||
int rectY = mouseRect.y();
|
||||
int rectW = mouseRect.width();
|
||||
int rectH = mouseRect.height();
|
||||
|
||||
if (pressedArea.at(0)) {
|
||||
int resizeW = this->width() - offsetX;
|
||||
if (this->minimumWidth() <= resizeW) {
|
||||
this->setGeometry(this->x() + offsetX, rectY, resizeW, rectH);
|
||||
}
|
||||
} else if (pressedArea.at(1)) {
|
||||
this->setGeometry(rectX, rectY, rectW + offsetX, rectH);
|
||||
} else if (pressedArea.at(2)) {
|
||||
int resizeH = this->height() - offsetY;
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(rectX, this->y() + offsetY, rectW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(3)) {
|
||||
this->setGeometry(rectX, rectY, rectW, rectH + offsetY);
|
||||
} else if (pressedArea.at(4)) {
|
||||
int resizeW = this->width() - offsetX;
|
||||
int resizeH = this->height() - offsetY;
|
||||
if (this->minimumWidth() <= resizeW) {
|
||||
this->setGeometry(this->x() + offsetX, this->y(), resizeW, resizeH);
|
||||
}
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(this->x(), this->y() + offsetY, resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(5)) {
|
||||
int resizeW = rectW + offsetX;
|
||||
int resizeH = this->height() - offsetY;
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(this->x(), this->y() + offsetY, resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(6)) {
|
||||
int resizeW = this->width() - offsetX;
|
||||
int resizeH = rectH + offsetY;
|
||||
if (this->minimumWidth() <= resizeW) {
|
||||
this->setGeometry(this->x() + offsetX, this->y(), resizeW, resizeH);
|
||||
}
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(this->x(), this->y(), resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(7)) {
|
||||
int resizeW = rectW + offsetX;
|
||||
int resizeH = rectH + offsetY;
|
||||
this->setGeometry(this->x(), this->y(), resizeW, resizeH);
|
||||
}
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseButtonPress) {
|
||||
//记住鼠标按下的坐标+窗体区域
|
||||
QMouseEvent *mouseEvent = (QMouseEvent *)event;
|
||||
mousePoint = mouseEvent->pos();
|
||||
mouseRect = this->geometry();
|
||||
|
||||
//判断按下的手柄的区域位置
|
||||
if (pressedRect.at(0).contains(mousePoint)) {
|
||||
pressedArea[0] = true;
|
||||
} else if (pressedRect.at(1).contains(mousePoint)) {
|
||||
pressedArea[1] = true;
|
||||
} else if (pressedRect.at(2).contains(mousePoint)) {
|
||||
pressedArea[2] = true;
|
||||
} else if (pressedRect.at(3).contains(mousePoint)) {
|
||||
pressedArea[3] = true;
|
||||
} else if (pressedRect.at(4).contains(mousePoint)) {
|
||||
pressedArea[4] = true;
|
||||
} else if (pressedRect.at(5).contains(mousePoint)) {
|
||||
pressedArea[5] = true;
|
||||
} else if (pressedRect.at(6).contains(mousePoint)) {
|
||||
pressedArea[6] = true;
|
||||
} else if (pressedRect.at(7).contains(mousePoint)) {
|
||||
pressedArea[7] = true;
|
||||
} else {
|
||||
mousePressed = true;
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseMove) {
|
||||
//改成用HoverMove识别
|
||||
} else if (event->type() == QEvent::MouseButtonRelease) {
|
||||
//恢复所有
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
mousePressed = false;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
pressedArea[i] = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FramelessDialog::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (watched == this) {
|
||||
if (event->type() == QEvent::WindowStateChange) {
|
||||
doWindowStateChange(event);
|
||||
} else {
|
||||
doResizeEvent(event);
|
||||
}
|
||||
} else if (watched == titleBar) {
|
||||
//双击标题栏发出双击信号给主界面
|
||||
//下面的 *result = HTCAPTION; 标志位也会自动识别双击标题栏
|
||||
#ifndef Q_OS_WIN
|
||||
if (event->type() == QEvent::MouseButtonDblClick) {
|
||||
emit titleDblClick();
|
||||
} else if (event->type() == QEvent::NonClientAreaMouseButtonDblClick) {
|
||||
emit titleDblClick();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return QDialog::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
bool FramelessDialog::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
||||
#else
|
||||
bool FramelessDialog::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
#endif
|
||||
{
|
||||
if (eventType == "windows_generic_MSG") {
|
||||
#ifdef Q_OS_WIN
|
||||
MSG *msg = static_cast<MSG *>(message);
|
||||
//qDebug() << TIMEMS << "nativeEvent" << msg->wParam << msg->message;
|
||||
|
||||
//不同的消息类型和参数进行不同的处理
|
||||
if (msg->message == WM_NCCALCSIZE) {
|
||||
*result = 0;
|
||||
return true;
|
||||
} else if (msg->message == WM_SYSKEYDOWN) {
|
||||
//屏蔽alt键按下
|
||||
} else if (msg->message == WM_SYSKEYUP) {
|
||||
//屏蔽alt键松开
|
||||
} else if (msg->message == WM_NCHITTEST) {
|
||||
//计算鼠标对应的屏幕坐标
|
||||
//这里最开始用的 LOWORD HIWORD 在多屏幕的时候会有问题
|
||||
//官方说明在这里 https://docs.microsoft.com/zh-cn/windows/win32/inputdev/wm-nchittest
|
||||
long x = GET_X_LPARAM(msg->lParam);
|
||||
long y = GET_Y_LPARAM(msg->lParam);
|
||||
QPoint pos = mapFromGlobal(QPoint(x, y));
|
||||
|
||||
//判断当前鼠标位置在哪个区域
|
||||
bool left = pos.x() < padding;
|
||||
bool right = pos.x() > width() - padding;
|
||||
bool top = pos.y() < padding;
|
||||
bool bottom = pos.y() > height() - padding;
|
||||
|
||||
//鼠标移动到四个角,这个消息是当鼠标移动或者有鼠标键按下时候发出的
|
||||
*result = 0;
|
||||
if (resizeEnable) {
|
||||
if (left && top) {
|
||||
*result = HTTOPLEFT;
|
||||
} else if (left && bottom) {
|
||||
*result = HTBOTTOMLEFT;
|
||||
} else if (right && top) {
|
||||
*result = HTTOPRIGHT;
|
||||
} else if (right && bottom) {
|
||||
*result = HTBOTTOMRIGHT;
|
||||
} else if (left) {
|
||||
*result = HTLEFT;
|
||||
} else if (right) {
|
||||
*result = HTRIGHT;
|
||||
} else if (top) {
|
||||
*result = HTTOP;
|
||||
} else if (bottom) {
|
||||
*result = HTBOTTOM;
|
||||
}
|
||||
}
|
||||
|
||||
//先处理掉拉伸
|
||||
if (0 != *result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//识别标题栏拖动产生半屏全屏效果
|
||||
if (titleBar && titleBar->rect().contains(pos)) {
|
||||
QWidget *child = titleBar->childAt(pos);
|
||||
if (!child) {
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (msg->wParam == PBT_APMSUSPEND && msg->message == WM_POWERBROADCAST) {
|
||||
//系统休眠的时候自动最小化可以规避程序可能出现的问题
|
||||
this->showMinimized();
|
||||
} else if (msg->wParam == PBT_APMRESUMEAUTOMATIC) {
|
||||
//休眠唤醒后自动打开
|
||||
this->showNormal();
|
||||
}
|
||||
#endif
|
||||
} else if (eventType == "NSEvent") {
|
||||
#ifdef Q_OS_MACOS
|
||||
#endif
|
||||
} else if (eventType == "xcb_generic_event_t") {
|
||||
#ifdef Q_OS_LINUX
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
|
||||
#ifdef Q_OS_WIN
|
||||
bool FramelessDialog::winEvent(MSG *message, long *result)
|
||||
{
|
||||
return nativeEvent("windows_generic_MSG", message, result);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void FramelessDialog::setPadding(int padding)
|
||||
{
|
||||
this->padding = padding;
|
||||
}
|
||||
|
||||
void FramelessDialog::setMoveEnable(bool moveEnable)
|
||||
{
|
||||
this->moveEnable = moveEnable;
|
||||
}
|
||||
|
||||
void FramelessDialog::setResizeEnable(bool resizeEnable)
|
||||
{
|
||||
this->resizeEnable = resizeEnable;
|
||||
}
|
||||
|
||||
void FramelessDialog::setTitleBar(QWidget *titleBar)
|
||||
{
|
||||
this->titleBar = titleBar;
|
||||
this->titleBar->installEventFilter(this);
|
||||
}
|
||||
|
||||
|
96
framelesscore/framelessdialog.h
Normal file
96
framelesscore/framelessdialog.h
Normal file
@ -0,0 +1,96 @@
|
||||
#ifndef FRAMELESSDIALOG_H
|
||||
#define FRAMELESSDIALOG_H
|
||||
|
||||
/**
|
||||
* 无边框窗体类 作者:feiyangqingyun(QQ:517216493) 2021-07-27
|
||||
* 1. 同时支持Qt4-Qt6,亲测Qt4.7到Qt6.2。
|
||||
* 2. 同时支持mingw、msvc、gcc等。
|
||||
* 3. 同时支持windows、linux、mac。
|
||||
* 4. 同时支持QMainWindow、QWidget、QDialog。
|
||||
* 5. 使用方法极其简单,只需要将继承类修改即可。
|
||||
* 6. 自动识别双击标题栏响应。
|
||||
* 7. 无边框拉伸在windows下不抖动。
|
||||
* 8. 在windows下具有移动到边缘半屏、移动到顶部全屏特性。
|
||||
* 9. 解决mac系统上无边框最小化最大化失效的bug。
|
||||
* 10. 解决系统休眠后再次启动程序懵逼的bug。
|
||||
* 11. 解决有时候窗体重新显示的时候假死不刷新的bug。
|
||||
* 12. 轻量级,1个代码文件,核心代码行数不到300行。
|
||||
* 13. 注释详细,示例完美,非常适合阅读和学习。
|
||||
* 14. 开源开箱即用,保证任意Qt版本可正常编译运行,无需任何调整。
|
||||
*/
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#ifdef quc
|
||||
class Q_DECL_EXPORT FramelessDialog : public QDialog
|
||||
#else
|
||||
class FramelessDialog : public QDialog
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FramelessDialog(QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
//窗体显示的时候触发
|
||||
void showEvent(QShowEvent *event);
|
||||
|
||||
//事件过滤器识别拖动拉伸等
|
||||
void doWindowStateChange(QEvent *event);
|
||||
void doResizeEvent(QEvent *event);
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
//拦截系统事件用于修复系统休眠后唤醒程序的bug
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result);
|
||||
#else
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
|
||||
#endif
|
||||
|
||||
//Qt4的写法
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
|
||||
#ifdef Q_OS_WIN
|
||||
bool winEvent(MSG *message, long *result);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
//边距+可移动+可拉伸
|
||||
int padding;
|
||||
bool moveEnable;
|
||||
bool resizeEnable;
|
||||
|
||||
//标题栏控件
|
||||
QWidget *titleBar;
|
||||
|
||||
//鼠标是否按下+按下坐标+按下时窗体区域
|
||||
bool mousePressed;
|
||||
QPoint mousePoint;
|
||||
QRect mouseRect;
|
||||
|
||||
//鼠标是否按下某个区域+按下区域的大小
|
||||
//依次为 左侧+右侧+上侧+下侧+左上侧+右上侧+左下侧+右下侧
|
||||
QList<bool> pressedArea;
|
||||
QList<QRect> pressedRect;
|
||||
|
||||
//记录是否最小化
|
||||
bool isMin;
|
||||
//存储窗体默认的属性
|
||||
Qt::WindowFlags flags;
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置边距+可拖动+可拉伸
|
||||
void setPadding(int padding);
|
||||
void setMoveEnable(bool moveEnable);
|
||||
void setResizeEnable(bool resizeEnable);
|
||||
|
||||
//设置标题栏控件
|
||||
void setTitleBar(QWidget *titleBar);
|
||||
|
||||
Q_SIGNALS:
|
||||
void titleDblClick();
|
||||
void windowStateChange(bool max);
|
||||
};
|
||||
|
||||
#endif // FRAMELESSDIALOG_H
|
375
framelesscore/framelessmainwindow.cpp
Normal file
375
framelesscore/framelessmainwindow.cpp
Normal file
@ -0,0 +1,375 @@
|
||||
#include "framelessmainwindow.h"
|
||||
#include "qdatetime.h"
|
||||
#include "qevent.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "windows.h"
|
||||
#include "windowsx.h"
|
||||
#pragma comment (lib,"user32.lib")
|
||||
#endif
|
||||
|
||||
#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
|
||||
|
||||
FramelessMainWindow::FramelessMainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
{
|
||||
padding = 8;
|
||||
moveEnable = true;
|
||||
resizeEnable = true;
|
||||
|
||||
mousePressed = false;
|
||||
mousePoint = QPoint(0, 0);
|
||||
mouseRect = QRect(0, 0, 0, 0);
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
pressedArea << false;
|
||||
pressedRect << QRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
isMin = false;
|
||||
flags = this->windowFlags();
|
||||
titleBar = 0;
|
||||
|
||||
//设置背景透明 官方在5.3以后才彻底修复 WA_TranslucentBackground+FramelessWindowHint 并存不绘制的bug
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,3,0))
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
#endif
|
||||
//设置无边框属性
|
||||
this->setWindowFlags(flags | Qt::FramelessWindowHint);
|
||||
//安装事件过滤器识别拖动
|
||||
this->installEventFilter(this);
|
||||
|
||||
//设置属性产生win窗体效果,移动到边缘半屏或者最大化等
|
||||
//设置以后会产生标题栏,需要在下面拦截消息WM_NCCALCSIZE重新去掉
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = (HWND)this->winId();
|
||||
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
|
||||
::SetWindowLong(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessMainWindow::showEvent(QShowEvent *event)
|
||||
{
|
||||
//解决有时候窗体重新显示的时候假死不刷新的bug
|
||||
setAttribute(Qt::WA_Mapped);
|
||||
QMainWindow::showEvent(event);
|
||||
}
|
||||
|
||||
void FramelessMainWindow::doWindowStateChange(QEvent *event)
|
||||
{
|
||||
//非最大化才能移动和拖动大小
|
||||
if (windowState() == Qt::WindowNoState) {
|
||||
moveEnable = true;
|
||||
resizeEnable = true;
|
||||
} else {
|
||||
moveEnable = false;
|
||||
resizeEnable = false;
|
||||
}
|
||||
|
||||
//发出最大化最小化等改变事件,以便界面上更改对应的信息比如右上角图标和文字
|
||||
emit windowStateChange(!moveEnable);
|
||||
|
||||
//解决mac系统上无边框最小化失效的bug
|
||||
#ifdef Q_OS_MACOS
|
||||
if (windowState() & Qt::WindowMinimized) {
|
||||
isMin = true;
|
||||
} else {
|
||||
if (isMin) {
|
||||
//设置无边框属性
|
||||
this->setWindowFlags(flags | Qt::FramelessWindowHint);
|
||||
this->setVisible(true);
|
||||
isMin = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessMainWindow::doResizeEvent(QEvent *event)
|
||||
{
|
||||
//非win系统的无边框拉伸,win系统上已经采用了nativeEvent来处理拉伸
|
||||
//为何不统一用计算的方式因为在win上用这个方式往左拉伸会发抖妹的
|
||||
#ifndef Q_OS_WIN
|
||||
if (event->type() == QEvent::Resize) {
|
||||
//重新计算八个描点的区域,描点区域的作用还有就是计算鼠标坐标是否在某一个区域内
|
||||
int width = this->width();
|
||||
int height = this->height();
|
||||
|
||||
//左侧描点区域
|
||||
pressedRect[0] = QRect(0, padding, padding, height - padding * 2);
|
||||
//右侧描点区域
|
||||
pressedRect[1] = QRect(width - padding, padding, padding, height - padding * 2);
|
||||
//上侧描点区域
|
||||
pressedRect[2] = QRect(padding, 0, width - padding * 2, padding);
|
||||
//下侧描点区域
|
||||
pressedRect[3] = QRect(padding, height - padding, width - padding * 2, padding);
|
||||
|
||||
//左上角描点区域
|
||||
pressedRect[4] = QRect(0, 0, padding, padding);
|
||||
//右上角描点区域
|
||||
pressedRect[5] = QRect(width - padding, 0, padding, padding);
|
||||
//左下角描点区域
|
||||
pressedRect[6] = QRect(0, height - padding, padding, padding);
|
||||
//右下角描点区域
|
||||
pressedRect[7] = QRect(width - padding, height - padding, padding, padding);
|
||||
} else if (event->type() == QEvent::HoverMove) {
|
||||
//设置对应鼠标形状,这个必须放在这里而不是下面,因为可以在鼠标没有按下的时候识别
|
||||
QHoverEvent *hoverEvent = (QHoverEvent *)event;
|
||||
QPoint point = hoverEvent->pos();
|
||||
if (resizeEnable) {
|
||||
if (pressedRect.at(0).contains(point)) {
|
||||
this->setCursor(Qt::SizeHorCursor);
|
||||
} else if (pressedRect.at(1).contains(point)) {
|
||||
this->setCursor(Qt::SizeHorCursor);
|
||||
} else if (pressedRect.at(2).contains(point)) {
|
||||
this->setCursor(Qt::SizeVerCursor);
|
||||
} else if (pressedRect.at(3).contains(point)) {
|
||||
this->setCursor(Qt::SizeVerCursor);
|
||||
} else if (pressedRect.at(4).contains(point)) {
|
||||
this->setCursor(Qt::SizeFDiagCursor);
|
||||
} else if (pressedRect.at(5).contains(point)) {
|
||||
this->setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (pressedRect.at(6).contains(point)) {
|
||||
this->setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (pressedRect.at(7).contains(point)) {
|
||||
this->setCursor(Qt::SizeFDiagCursor);
|
||||
} else {
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
}
|
||||
|
||||
//根据当前鼠标位置,计算XY轴移动了多少
|
||||
int offsetX = point.x() - mousePoint.x();
|
||||
int offsetY = point.y() - mousePoint.y();
|
||||
|
||||
//根据按下处的位置判断是否是移动控件还是拉伸控件
|
||||
if (moveEnable && mousePressed) {
|
||||
this->move(this->x() + offsetX, this->y() + offsetY);
|
||||
}
|
||||
|
||||
if (resizeEnable) {
|
||||
int rectX = mouseRect.x();
|
||||
int rectY = mouseRect.y();
|
||||
int rectW = mouseRect.width();
|
||||
int rectH = mouseRect.height();
|
||||
|
||||
if (pressedArea.at(0)) {
|
||||
int resizeW = this->width() - offsetX;
|
||||
if (this->minimumWidth() <= resizeW) {
|
||||
this->setGeometry(this->x() + offsetX, rectY, resizeW, rectH);
|
||||
}
|
||||
} else if (pressedArea.at(1)) {
|
||||
this->setGeometry(rectX, rectY, rectW + offsetX, rectH);
|
||||
} else if (pressedArea.at(2)) {
|
||||
int resizeH = this->height() - offsetY;
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(rectX, this->y() + offsetY, rectW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(3)) {
|
||||
this->setGeometry(rectX, rectY, rectW, rectH + offsetY);
|
||||
} else if (pressedArea.at(4)) {
|
||||
int resizeW = this->width() - offsetX;
|
||||
int resizeH = this->height() - offsetY;
|
||||
if (this->minimumWidth() <= resizeW) {
|
||||
this->setGeometry(this->x() + offsetX, this->y(), resizeW, resizeH);
|
||||
}
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(this->x(), this->y() + offsetY, resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(5)) {
|
||||
int resizeW = rectW + offsetX;
|
||||
int resizeH = this->height() - offsetY;
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(this->x(), this->y() + offsetY, resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(6)) {
|
||||
int resizeW = this->width() - offsetX;
|
||||
int resizeH = rectH + offsetY;
|
||||
if (this->minimumWidth() <= resizeW) {
|
||||
this->setGeometry(this->x() + offsetX, this->y(), resizeW, resizeH);
|
||||
}
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(this->x(), this->y(), resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(7)) {
|
||||
int resizeW = rectW + offsetX;
|
||||
int resizeH = rectH + offsetY;
|
||||
this->setGeometry(this->x(), this->y(), resizeW, resizeH);
|
||||
}
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseButtonPress) {
|
||||
//记住鼠标按下的坐标+窗体区域
|
||||
QMouseEvent *mouseEvent = (QMouseEvent *)event;
|
||||
mousePoint = mouseEvent->pos();
|
||||
mouseRect = this->geometry();
|
||||
|
||||
//判断按下的手柄的区域位置
|
||||
if (pressedRect.at(0).contains(mousePoint)) {
|
||||
pressedArea[0] = true;
|
||||
} else if (pressedRect.at(1).contains(mousePoint)) {
|
||||
pressedArea[1] = true;
|
||||
} else if (pressedRect.at(2).contains(mousePoint)) {
|
||||
pressedArea[2] = true;
|
||||
} else if (pressedRect.at(3).contains(mousePoint)) {
|
||||
pressedArea[3] = true;
|
||||
} else if (pressedRect.at(4).contains(mousePoint)) {
|
||||
pressedArea[4] = true;
|
||||
} else if (pressedRect.at(5).contains(mousePoint)) {
|
||||
pressedArea[5] = true;
|
||||
} else if (pressedRect.at(6).contains(mousePoint)) {
|
||||
pressedArea[6] = true;
|
||||
} else if (pressedRect.at(7).contains(mousePoint)) {
|
||||
pressedArea[7] = true;
|
||||
} else {
|
||||
mousePressed = true;
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseMove) {
|
||||
//改成用HoverMove识别
|
||||
} else if (event->type() == QEvent::MouseButtonRelease) {
|
||||
//恢复所有
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
mousePressed = false;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
pressedArea[i] = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FramelessMainWindow::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (watched == this) {
|
||||
if (event->type() == QEvent::WindowStateChange) {
|
||||
doWindowStateChange(event);
|
||||
} else {
|
||||
doResizeEvent(event);
|
||||
}
|
||||
} else if (watched == titleBar) {
|
||||
//双击标题栏发出双击信号给主界面
|
||||
//下面的 *result = HTCAPTION; 标志位也会自动识别双击标题栏
|
||||
#ifndef Q_OS_WIN
|
||||
if (event->type() == QEvent::MouseButtonDblClick) {
|
||||
emit titleDblClick();
|
||||
} else if (event->type() == QEvent::NonClientAreaMouseButtonDblClick) {
|
||||
emit titleDblClick();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return QMainWindow::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
bool FramelessMainWindow::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
||||
#else
|
||||
bool FramelessMainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
#endif
|
||||
{
|
||||
if (eventType == "windows_generic_MSG") {
|
||||
#ifdef Q_OS_WIN
|
||||
MSG *msg = static_cast<MSG *>(message);
|
||||
//qDebug() << TIMEMS << "nativeEvent" << msg->wParam << msg->message;
|
||||
|
||||
//不同的消息类型和参数进行不同的处理
|
||||
if (msg->message == WM_NCCALCSIZE) {
|
||||
*result = 0;
|
||||
return true;
|
||||
} else if (msg->message == WM_SYSKEYDOWN) {
|
||||
//屏蔽alt键按下
|
||||
} else if (msg->message == WM_SYSKEYUP) {
|
||||
//屏蔽alt键松开
|
||||
} else if (msg->message == WM_NCHITTEST) {
|
||||
//计算鼠标对应的屏幕坐标
|
||||
//这里最开始用的 LOWORD HIWORD 在多屏幕的时候会有问题
|
||||
//官方说明在这里 https://docs.microsoft.com/zh-cn/windows/win32/inputdev/wm-nchittest
|
||||
long x = GET_X_LPARAM(msg->lParam);
|
||||
long y = GET_Y_LPARAM(msg->lParam);
|
||||
QPoint pos = mapFromGlobal(QPoint(x, y));
|
||||
|
||||
//判断当前鼠标位置在哪个区域
|
||||
bool left = pos.x() < padding;
|
||||
bool right = pos.x() > width() - padding;
|
||||
bool top = pos.y() < padding;
|
||||
bool bottom = pos.y() > height() - padding;
|
||||
|
||||
//鼠标移动到四个角,这个消息是当鼠标移动或者有鼠标键按下时候发出的
|
||||
*result = 0;
|
||||
if (resizeEnable) {
|
||||
if (left && top) {
|
||||
*result = HTTOPLEFT;
|
||||
} else if (left && bottom) {
|
||||
*result = HTBOTTOMLEFT;
|
||||
} else if (right && top) {
|
||||
*result = HTTOPRIGHT;
|
||||
} else if (right && bottom) {
|
||||
*result = HTBOTTOMRIGHT;
|
||||
} else if (left) {
|
||||
*result = HTLEFT;
|
||||
} else if (right) {
|
||||
*result = HTRIGHT;
|
||||
} else if (top) {
|
||||
*result = HTTOP;
|
||||
} else if (bottom) {
|
||||
*result = HTBOTTOM;
|
||||
}
|
||||
}
|
||||
|
||||
//先处理掉拉伸
|
||||
if (0 != *result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//识别标题栏拖动产生半屏全屏效果
|
||||
if (titleBar && titleBar->rect().contains(pos)) {
|
||||
QWidget *child = titleBar->childAt(pos);
|
||||
if (!child) {
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (msg->wParam == PBT_APMSUSPEND && msg->message == WM_POWERBROADCAST) {
|
||||
//系统休眠的时候自动最小化可以规避程序可能出现的问题
|
||||
this->showMinimized();
|
||||
} else if (msg->wParam == PBT_APMRESUMEAUTOMATIC) {
|
||||
//休眠唤醒后自动打开
|
||||
this->showNormal();
|
||||
}
|
||||
#endif
|
||||
} else if (eventType == "NSEvent") {
|
||||
#ifdef Q_OS_MACOS
|
||||
#endif
|
||||
} else if (eventType == "xcb_generic_event_t") {
|
||||
#ifdef Q_OS_LINUX
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
|
||||
#ifdef Q_OS_WIN
|
||||
bool FramelessMainWindow::winEvent(MSG *message, long *result)
|
||||
{
|
||||
return nativeEvent("windows_generic_MSG", message, result);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void FramelessMainWindow::setPadding(int padding)
|
||||
{
|
||||
this->padding = padding;
|
||||
}
|
||||
|
||||
void FramelessMainWindow::setMoveEnable(bool moveEnable)
|
||||
{
|
||||
this->moveEnable = moveEnable;
|
||||
}
|
||||
|
||||
void FramelessMainWindow::setResizeEnable(bool resizeEnable)
|
||||
{
|
||||
this->resizeEnable = resizeEnable;
|
||||
}
|
||||
|
||||
void FramelessMainWindow::setTitleBar(QWidget *titleBar)
|
||||
{
|
||||
this->titleBar = titleBar;
|
||||
this->titleBar->installEventFilter(this);
|
||||
}
|
96
framelesscore/framelessmainwindow.h
Normal file
96
framelesscore/framelessmainwindow.h
Normal file
@ -0,0 +1,96 @@
|
||||
#ifndef FRAMELESSMAINWINDOW_H
|
||||
#define FRAMELESSMAINWINDOW_H
|
||||
|
||||
/**
|
||||
* 无边框窗体类 作者:feiyangqingyun(QQ:517216493) 2021-07-27
|
||||
* 1. 同时支持Qt4-Qt6,亲测Qt4.7到Qt6.2。
|
||||
* 2. 同时支持mingw、msvc、gcc等。
|
||||
* 3. 同时支持windows、linux、mac。
|
||||
* 4. 同时支持QMainWindow、QWidget、QDialog。
|
||||
* 5. 使用方法极其简单,只需要将继承类修改即可。
|
||||
* 6. 自动识别双击标题栏响应。
|
||||
* 7. 无边框拉伸在windows下不抖动。
|
||||
* 8. 在windows下具有移动到边缘半屏、移动到顶部全屏特性。
|
||||
* 9. 解决mac系统上无边框最小化最大化失效的bug。
|
||||
* 10. 解决系统休眠后再次启动程序懵逼的bug。
|
||||
* 11. 解决有时候窗体重新显示的时候假死不刷新的bug。
|
||||
* 12. 轻量级,1个代码文件,核心代码行数不到300行。
|
||||
* 13. 注释详细,示例完美,非常适合阅读和学习。
|
||||
* 14. 开源开箱即用,保证任意Qt版本可正常编译运行,无需任何调整。
|
||||
*/
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#ifdef quc
|
||||
class Q_DECL_EXPORT FramelessMainWindow : public QMainWindow
|
||||
#else
|
||||
class FramelessMainWindow : public QMainWindow
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FramelessMainWindow(QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
//窗体显示的时候触发
|
||||
void showEvent(QShowEvent *event);
|
||||
|
||||
//事件过滤器识别拖动拉伸等
|
||||
void doWindowStateChange(QEvent *event);
|
||||
void doResizeEvent(QEvent *event);
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
//拦截系统事件用于修复系统休眠后唤醒程序的bug
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result);
|
||||
#else
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
|
||||
#endif
|
||||
|
||||
//Qt4的写法
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
|
||||
#ifdef Q_OS_WIN
|
||||
bool winEvent(MSG *message, long *result);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
//边距+可移动+可拉伸
|
||||
int padding;
|
||||
bool moveEnable;
|
||||
bool resizeEnable;
|
||||
|
||||
//标题栏控件
|
||||
QWidget *titleBar;
|
||||
|
||||
//鼠标是否按下+按下坐标+按下时窗体区域
|
||||
bool mousePressed;
|
||||
QPoint mousePoint;
|
||||
QRect mouseRect;
|
||||
|
||||
//鼠标是否按下某个区域+按下区域的大小
|
||||
//依次为 左侧+右侧+上侧+下侧+左上侧+右上侧+左下侧+右下侧
|
||||
QList<bool> pressedArea;
|
||||
QList<QRect> pressedRect;
|
||||
|
||||
//记录是否最小化
|
||||
bool isMin;
|
||||
//存储窗体默认的属性
|
||||
Qt::WindowFlags flags;
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置边距+可拖动+可拉伸
|
||||
void setPadding(int padding);
|
||||
void setMoveEnable(bool moveEnable);
|
||||
void setResizeEnable(bool resizeEnable);
|
||||
|
||||
//设置标题栏控件
|
||||
void setTitleBar(QWidget *titleBar);
|
||||
|
||||
Q_SIGNALS:
|
||||
void titleDblClick();
|
||||
void windowStateChange(bool max);
|
||||
};
|
||||
|
||||
#endif // FRAMELESSMAINWINDOW_H
|
377
framelesscore/framelesswidget.cpp
Normal file
377
framelesscore/framelesswidget.cpp
Normal file
@ -0,0 +1,377 @@
|
||||
#include "framelesswidget.h"
|
||||
#include "qdatetime.h"
|
||||
#include "qevent.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "windows.h"
|
||||
#include "windowsx.h"
|
||||
#pragma comment (lib,"user32.lib")
|
||||
#endif
|
||||
|
||||
#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
|
||||
|
||||
FramelessWidget::FramelessWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
padding = 8;
|
||||
moveEnable = true;
|
||||
resizeEnable = true;
|
||||
|
||||
mousePressed = false;
|
||||
mousePoint = QPoint(0, 0);
|
||||
mouseRect = QRect(0, 0, 0, 0);
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
pressedArea << false;
|
||||
pressedRect << QRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
isMin = false;
|
||||
flags = this->windowFlags();
|
||||
titleBar = 0;
|
||||
|
||||
//设置背景透明 官方在5.3以后才彻底修复 WA_TranslucentBackground+FramelessWindowHint 并存不绘制的bug
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,3,0))
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
#endif
|
||||
//设置无边框属性
|
||||
this->setWindowFlags(flags | Qt::FramelessWindowHint);
|
||||
//安装事件过滤器识别拖动
|
||||
this->installEventFilter(this);
|
||||
|
||||
//设置属性产生win窗体效果,移动到边缘半屏或者最大化等
|
||||
//设置以后会产生标题栏需要在下面拦截消息重新去掉
|
||||
#ifdef Q_OS_WIN
|
||||
HWND hwnd = (HWND)this->winId();
|
||||
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
|
||||
::SetWindowLong(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
//解决有时候窗体重新显示的时候假死不刷新的bug
|
||||
setAttribute(Qt::WA_Mapped);
|
||||
QWidget::showEvent(event);
|
||||
}
|
||||
|
||||
void FramelessWidget::doWindowStateChange(QEvent *event)
|
||||
{
|
||||
//非最大化才能移动和拖动大小
|
||||
if (windowState() == Qt::WindowNoState) {
|
||||
moveEnable = true;
|
||||
resizeEnable = true;
|
||||
} else {
|
||||
moveEnable = false;
|
||||
resizeEnable = false;
|
||||
}
|
||||
|
||||
//发出最大化最小化等改变事件,以便界面上更改对应的信息比如右上角图标和文字
|
||||
emit windowStateChange(!moveEnable);
|
||||
|
||||
//解决mac系统上无边框最小化失效的bug
|
||||
#ifdef Q_OS_MACOS
|
||||
if (windowState() & Qt::WindowMinimized) {
|
||||
isMin = true;
|
||||
} else {
|
||||
if (isMin) {
|
||||
//设置无边框属性
|
||||
this->setWindowFlags(flags | Qt::FramelessWindowHint);
|
||||
this->setVisible(true);
|
||||
isMin = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FramelessWidget::doResizeEvent(QEvent *event)
|
||||
{
|
||||
//非win系统的无边框拉伸,win系统上已经采用了nativeEvent来处理拉伸
|
||||
//为何不统一用计算的方式因为在win上用这个方式往左拉伸会发抖妹的
|
||||
#ifndef Q_OS_WIN
|
||||
if (event->type() == QEvent::Resize) {
|
||||
//重新计算八个描点的区域,描点区域的作用还有就是计算鼠标坐标是否在某一个区域内
|
||||
int width = this->width();
|
||||
int height = this->height();
|
||||
|
||||
//左侧描点区域
|
||||
pressedRect[0] = QRect(0, padding, padding, height - padding * 2);
|
||||
//右侧描点区域
|
||||
pressedRect[1] = QRect(width - padding, padding, padding, height - padding * 2);
|
||||
//上侧描点区域
|
||||
pressedRect[2] = QRect(padding, 0, width - padding * 2, padding);
|
||||
//下侧描点区域
|
||||
pressedRect[3] = QRect(padding, height - padding, width - padding * 2, padding);
|
||||
|
||||
//左上角描点区域
|
||||
pressedRect[4] = QRect(0, 0, padding, padding);
|
||||
//右上角描点区域
|
||||
pressedRect[5] = QRect(width - padding, 0, padding, padding);
|
||||
//左下角描点区域
|
||||
pressedRect[6] = QRect(0, height - padding, padding, padding);
|
||||
//右下角描点区域
|
||||
pressedRect[7] = QRect(width - padding, height - padding, padding, padding);
|
||||
} else if (event->type() == QEvent::HoverMove) {
|
||||
//设置对应鼠标形状,这个必须放在这里而不是下面,因为可以在鼠标没有按下的时候识别
|
||||
QHoverEvent *hoverEvent = (QHoverEvent *)event;
|
||||
QPoint point = hoverEvent->pos();
|
||||
if (resizeEnable) {
|
||||
if (pressedRect.at(0).contains(point)) {
|
||||
this->setCursor(Qt::SizeHorCursor);
|
||||
} else if (pressedRect.at(1).contains(point)) {
|
||||
this->setCursor(Qt::SizeHorCursor);
|
||||
} else if (pressedRect.at(2).contains(point)) {
|
||||
this->setCursor(Qt::SizeVerCursor);
|
||||
} else if (pressedRect.at(3).contains(point)) {
|
||||
this->setCursor(Qt::SizeVerCursor);
|
||||
} else if (pressedRect.at(4).contains(point)) {
|
||||
this->setCursor(Qt::SizeFDiagCursor);
|
||||
} else if (pressedRect.at(5).contains(point)) {
|
||||
this->setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (pressedRect.at(6).contains(point)) {
|
||||
this->setCursor(Qt::SizeBDiagCursor);
|
||||
} else if (pressedRect.at(7).contains(point)) {
|
||||
this->setCursor(Qt::SizeFDiagCursor);
|
||||
} else {
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
}
|
||||
|
||||
//根据当前鼠标位置,计算XY轴移动了多少
|
||||
int offsetX = point.x() - mousePoint.x();
|
||||
int offsetY = point.y() - mousePoint.y();
|
||||
|
||||
//根据按下处的位置判断是否是移动控件还是拉伸控件
|
||||
if (moveEnable && mousePressed) {
|
||||
this->move(this->x() + offsetX, this->y() + offsetY);
|
||||
}
|
||||
|
||||
if (resizeEnable) {
|
||||
int rectX = mouseRect.x();
|
||||
int rectY = mouseRect.y();
|
||||
int rectW = mouseRect.width();
|
||||
int rectH = mouseRect.height();
|
||||
|
||||
if (pressedArea.at(0)) {
|
||||
int resizeW = this->width() - offsetX;
|
||||
if (this->minimumWidth() <= resizeW) {
|
||||
this->setGeometry(this->x() + offsetX, rectY, resizeW, rectH);
|
||||
}
|
||||
} else if (pressedArea.at(1)) {
|
||||
this->setGeometry(rectX, rectY, rectW + offsetX, rectH);
|
||||
} else if (pressedArea.at(2)) {
|
||||
int resizeH = this->height() - offsetY;
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(rectX, this->y() + offsetY, rectW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(3)) {
|
||||
this->setGeometry(rectX, rectY, rectW, rectH + offsetY);
|
||||
} else if (pressedArea.at(4)) {
|
||||
int resizeW = this->width() - offsetX;
|
||||
int resizeH = this->height() - offsetY;
|
||||
if (this->minimumWidth() <= resizeW) {
|
||||
this->setGeometry(this->x() + offsetX, this->y(), resizeW, resizeH);
|
||||
}
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(this->x(), this->y() + offsetY, resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(5)) {
|
||||
int resizeW = rectW + offsetX;
|
||||
int resizeH = this->height() - offsetY;
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(this->x(), this->y() + offsetY, resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(6)) {
|
||||
int resizeW = this->width() - offsetX;
|
||||
int resizeH = rectH + offsetY;
|
||||
if (this->minimumWidth() <= resizeW) {
|
||||
this->setGeometry(this->x() + offsetX, this->y(), resizeW, resizeH);
|
||||
}
|
||||
if (this->minimumHeight() <= resizeH) {
|
||||
this->setGeometry(this->x(), this->y(), resizeW, resizeH);
|
||||
}
|
||||
} else if (pressedArea.at(7)) {
|
||||
int resizeW = rectW + offsetX;
|
||||
int resizeH = rectH + offsetY;
|
||||
this->setGeometry(this->x(), this->y(), resizeW, resizeH);
|
||||
}
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseButtonPress) {
|
||||
//记住鼠标按下的坐标+窗体区域
|
||||
QMouseEvent *mouseEvent = (QMouseEvent *)event;
|
||||
mousePoint = mouseEvent->pos();
|
||||
mouseRect = this->geometry();
|
||||
|
||||
//判断按下的手柄的区域位置
|
||||
if (pressedRect.at(0).contains(mousePoint)) {
|
||||
pressedArea[0] = true;
|
||||
} else if (pressedRect.at(1).contains(mousePoint)) {
|
||||
pressedArea[1] = true;
|
||||
} else if (pressedRect.at(2).contains(mousePoint)) {
|
||||
pressedArea[2] = true;
|
||||
} else if (pressedRect.at(3).contains(mousePoint)) {
|
||||
pressedArea[3] = true;
|
||||
} else if (pressedRect.at(4).contains(mousePoint)) {
|
||||
pressedArea[4] = true;
|
||||
} else if (pressedRect.at(5).contains(mousePoint)) {
|
||||
pressedArea[5] = true;
|
||||
} else if (pressedRect.at(6).contains(mousePoint)) {
|
||||
pressedArea[6] = true;
|
||||
} else if (pressedRect.at(7).contains(mousePoint)) {
|
||||
pressedArea[7] = true;
|
||||
} else {
|
||||
mousePressed = true;
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseMove) {
|
||||
//改成用HoverMove识别
|
||||
} else if (event->type() == QEvent::MouseButtonRelease) {
|
||||
//恢复所有
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
mousePressed = false;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
pressedArea[i] = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FramelessWidget::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (watched == this) {
|
||||
if (event->type() == QEvent::WindowStateChange) {
|
||||
doWindowStateChange(event);
|
||||
} else {
|
||||
doResizeEvent(event);
|
||||
}
|
||||
} else if (watched == titleBar) {
|
||||
//双击标题栏发出双击信号给主界面
|
||||
//下面的 *result = HTCAPTION; 标志位也会自动识别双击标题栏
|
||||
#ifndef Q_OS_WIN
|
||||
if (event->type() == QEvent::MouseButtonDblClick) {
|
||||
emit titleDblClick();
|
||||
} else if (event->type() == QEvent::NonClientAreaMouseButtonDblClick) {
|
||||
emit titleDblClick();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
bool FramelessWidget::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
||||
#else
|
||||
bool FramelessWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
#endif
|
||||
{
|
||||
if (eventType == "windows_generic_MSG") {
|
||||
#ifdef Q_OS_WIN
|
||||
MSG *msg = static_cast<MSG *>(message);
|
||||
//qDebug() << TIMEMS << "nativeEvent" << msg->wParam << msg->message;
|
||||
|
||||
//不同的消息类型和参数进行不同的处理
|
||||
if (msg->message == WM_NCCALCSIZE) {
|
||||
*result = 0;
|
||||
return true;
|
||||
} else if (msg->message == WM_SYSKEYDOWN) {
|
||||
//屏蔽alt键按下
|
||||
} else if (msg->message == WM_SYSKEYUP) {
|
||||
//屏蔽alt键松开
|
||||
} else if (msg->message == WM_NCHITTEST) {
|
||||
//计算鼠标对应的屏幕坐标
|
||||
//这里最开始用的 LOWORD HIWORD 在多屏幕的时候会有问题
|
||||
//官方说明在这里 https://docs.microsoft.com/zh-cn/windows/win32/inputdev/wm-nchittest
|
||||
long x = GET_X_LPARAM(msg->lParam);
|
||||
long y = GET_Y_LPARAM(msg->lParam);
|
||||
QPoint pos = mapFromGlobal(QPoint(x, y));
|
||||
|
||||
//判断当前鼠标位置在哪个区域
|
||||
bool left = pos.x() < padding;
|
||||
bool right = pos.x() > width() - padding;
|
||||
bool top = pos.y() < padding;
|
||||
bool bottom = pos.y() > height() - padding;
|
||||
|
||||
//鼠标移动到四个角,这个消息是当鼠标移动或者有鼠标键按下时候发出的
|
||||
*result = 0;
|
||||
if (resizeEnable) {
|
||||
if (left && top) {
|
||||
*result = HTTOPLEFT;
|
||||
} else if (left && bottom) {
|
||||
*result = HTBOTTOMLEFT;
|
||||
} else if (right && top) {
|
||||
*result = HTTOPRIGHT;
|
||||
} else if (right && bottom) {
|
||||
*result = HTBOTTOMRIGHT;
|
||||
} else if (left) {
|
||||
*result = HTLEFT;
|
||||
} else if (right) {
|
||||
*result = HTRIGHT;
|
||||
} else if (top) {
|
||||
*result = HTTOP;
|
||||
} else if (bottom) {
|
||||
*result = HTBOTTOM;
|
||||
}
|
||||
}
|
||||
|
||||
//先处理掉拉伸
|
||||
if (0 != *result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//识别标题栏拖动产生半屏全屏效果
|
||||
if (titleBar && titleBar->rect().contains(pos)) {
|
||||
QWidget *child = titleBar->childAt(pos);
|
||||
if (!child) {
|
||||
*result = HTCAPTION;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (msg->wParam == PBT_APMSUSPEND && msg->message == WM_POWERBROADCAST) {
|
||||
//系统休眠的时候自动最小化可以规避程序可能出现的问题
|
||||
this->showMinimized();
|
||||
} else if (msg->wParam == PBT_APMRESUMEAUTOMATIC) {
|
||||
//休眠唤醒后自动打开
|
||||
this->showNormal();
|
||||
}
|
||||
#endif
|
||||
} else if (eventType == "NSEvent") {
|
||||
#ifdef Q_OS_MACOS
|
||||
#endif
|
||||
} else if (eventType == "xcb_generic_event_t") {
|
||||
#ifdef Q_OS_LINUX
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
|
||||
#ifdef Q_OS_WIN
|
||||
bool FramelessWidget::winEvent(MSG *message, long *result)
|
||||
{
|
||||
return nativeEvent("windows_generic_MSG", message, result);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void FramelessWidget::setPadding(int padding)
|
||||
{
|
||||
this->padding = padding;
|
||||
}
|
||||
|
||||
void FramelessWidget::setMoveEnable(bool moveEnable)
|
||||
{
|
||||
this->moveEnable = moveEnable;
|
||||
}
|
||||
|
||||
void FramelessWidget::setResizeEnable(bool resizeEnable)
|
||||
{
|
||||
this->resizeEnable = resizeEnable;
|
||||
}
|
||||
|
||||
void FramelessWidget::setTitleBar(QWidget *titleBar)
|
||||
{
|
||||
this->titleBar = titleBar;
|
||||
this->titleBar->installEventFilter(this);
|
||||
}
|
||||
|
||||
|
96
framelesscore/framelesswidget.h
Normal file
96
framelesscore/framelesswidget.h
Normal file
@ -0,0 +1,96 @@
|
||||
#ifndef FRAMELESSWIDGET_H
|
||||
#define FRAMELESSWIDGET_H
|
||||
|
||||
/**
|
||||
* 无边框窗体类 作者:feiyangqingyun(QQ:517216493) 2021-07-27
|
||||
* 1. 同时支持Qt4-Qt6,亲测Qt4.7到Qt6.2。
|
||||
* 2. 同时支持mingw、msvc、gcc等。
|
||||
* 3. 同时支持windows、linux、mac。
|
||||
* 4. 同时支持QMainWindow、QWidget、QDialog。
|
||||
* 5. 使用方法极其简单,只需要将继承类修改即可。
|
||||
* 6. 自动识别双击标题栏响应。
|
||||
* 7. 无边框拉伸在windows下不抖动。
|
||||
* 8. 在windows下具有移动到边缘半屏、移动到顶部全屏特性。
|
||||
* 9. 解决mac系统上无边框最小化最大化失效的bug。
|
||||
* 10. 解决系统休眠后再次启动程序懵逼的bug。
|
||||
* 11. 解决有时候窗体重新显示的时候假死不刷新的bug。
|
||||
* 12. 轻量级,1个代码文件,核心代码行数不到300行。
|
||||
* 13. 注释详细,示例完美,非常适合阅读和学习。
|
||||
* 14. 开源开箱即用,保证任意Qt版本可正常编译运行,无需任何调整。
|
||||
*/
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#ifdef quc
|
||||
class Q_DECL_EXPORT FramelessWidget : public QWidget
|
||||
#else
|
||||
class FramelessWidget : public QWidget
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FramelessWidget(QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
//窗体显示的时候触发
|
||||
void showEvent(QShowEvent *event);
|
||||
|
||||
//事件过滤器识别拖动拉伸等
|
||||
void doWindowStateChange(QEvent *event);
|
||||
void doResizeEvent(QEvent *event);
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
//拦截系统事件用于修复系统休眠后唤醒程序的bug
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result);
|
||||
#else
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
|
||||
#endif
|
||||
|
||||
//Qt4的写法
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
|
||||
#ifdef Q_OS_WIN
|
||||
bool winEvent(MSG *message, long *result);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
private:
|
||||
//边距+可移动+可拉伸
|
||||
int padding;
|
||||
bool moveEnable;
|
||||
bool resizeEnable;
|
||||
|
||||
//标题栏控件
|
||||
QWidget *titleBar;
|
||||
|
||||
//鼠标是否按下+按下坐标+按下时窗体区域
|
||||
bool mousePressed;
|
||||
QPoint mousePoint;
|
||||
QRect mouseRect;
|
||||
|
||||
//鼠标是否按下某个区域+按下区域的大小
|
||||
//依次为 左侧+右侧+上侧+下侧+左上侧+右上侧+左下侧+右下侧
|
||||
QList<bool> pressedArea;
|
||||
QList<QRect> pressedRect;
|
||||
|
||||
//记录是否最小化
|
||||
bool isMin;
|
||||
//存储窗体默认的属性
|
||||
Qt::WindowFlags flags;
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置边距+可拖动+可拉伸
|
||||
void setPadding(int padding);
|
||||
void setMoveEnable(bool moveEnable);
|
||||
void setResizeEnable(bool resizeEnable);
|
||||
|
||||
//设置标题栏控件
|
||||
void setTitleBar(QWidget *titleBar);
|
||||
|
||||
Q_SIGNALS:
|
||||
void titleDblClick();
|
||||
void windowStateChange(bool max);
|
||||
};
|
||||
|
||||
#endif // FRAMELESSWIDGET_H
|
66
keil_development_assistant.pro
Normal file
66
keil_development_assistant.pro
Normal file
@ -0,0 +1,66 @@
|
||||
QT += core gui xml charts printsupport
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any Qt feature that has been marked 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 it uses 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
|
||||
|
||||
|
||||
include($$PWD/framelesscore/framelesscore.pri)
|
||||
|
||||
|
||||
INCLUDEPATH +=$$PWD/framelesscore/
|
||||
|
||||
SOURCES += \
|
||||
find_path.cpp \
|
||||
flatui.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
only_run_by_file.cpp \
|
||||
parse_keil_project.cpp \
|
||||
parse_m51_from_keil.cpp \
|
||||
parse_map_from_keil.cpp \
|
||||
use_percentage_bar.cpp
|
||||
|
||||
HEADERS += \
|
||||
find_path.h \
|
||||
flatui.h \
|
||||
mainwindow.h \
|
||||
only_run_by_file.h \
|
||||
parse_keil_project.h \
|
||||
parse_m51_from_keil.h \
|
||||
parse_map_from_keil.h \
|
||||
use_percentage_bar.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
use_percentage_bar.ui
|
||||
|
||||
TRANSLATIONS += \
|
||||
keil_development_assistant_zh_CN.ts
|
||||
|
||||
RC_FILE =ico.rc
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
DISTFILES += \
|
||||
KDA_Logo.ico \
|
||||
ico.rc \
|
||||
qcustomplot/GPL.txt \
|
||||
qcustomplot/changelog.txt
|
||||
|
||||
RESOURCES += \
|
||||
R.qrc
|
3
keil_development_assistant_zh_CN.ts
Normal file
3
keil_development_assistant_zh_CN.ts
Normal file
@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="keil_development_assistant_zh_CN"></TS>
|
58
main.cpp
Normal file
58
main.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "mainwindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
#include <QSharedMemory>
|
||||
#include <QMessageBox>
|
||||
|
||||
MainWindow* main_window=nullptr;
|
||||
|
||||
#include "only_run_by_file.h"
|
||||
void onAppExit()
|
||||
{
|
||||
// 删除 run 文件
|
||||
QFile::remove("run");
|
||||
}
|
||||
|
||||
QString project_path;
|
||||
QString map_path;
|
||||
bool only_printf=false;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
// for(int i=0;i<argc;i++)
|
||||
// qDebug() <<argv[i];
|
||||
|
||||
if(argc>3)
|
||||
{
|
||||
project_path=argv[1];
|
||||
map_path=argv[2];
|
||||
only_printf=argv[3];
|
||||
|
||||
}else if(argc>2)
|
||||
{
|
||||
project_path=map_path=argv[1];
|
||||
only_printf=argv[2];
|
||||
}
|
||||
if(argc>1)
|
||||
{
|
||||
project_path="./";
|
||||
map_path="./";
|
||||
only_printf=argv[1];
|
||||
}
|
||||
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
|
||||
only_run_by_file programController;
|
||||
QObject::connect(&programController, &only_run_by_file::runFileDeleted, &a, &QCoreApplication::quit);
|
||||
// 注册程序退出的处理函数
|
||||
QObject::connect(&a, &QCoreApplication::aboutToQuit, onAppExit);
|
||||
|
||||
MainWindow w;
|
||||
|
||||
if(!only_printf) w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
764
mainwindow.cpp
Normal file
764
mainwindow.cpp
Normal file
@ -0,0 +1,764 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include "use_percentage_bar.h"
|
||||
|
||||
#include <Qdebug>
|
||||
#include "flatui.h"
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
extern MainWindow* main_window;
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
|
||||
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : FramelessMainWindow(parent), ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete cpu;
|
||||
delete map;
|
||||
delete ram_chart;
|
||||
delete flash_chart;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MainWindow::initForm()
|
||||
{
|
||||
//设置标题栏控件
|
||||
ui->labTitle->setText("一个极客开源::keil开发助手");
|
||||
this->setWindowTitle(ui->labTitle->text());
|
||||
this->setTitleBar(ui->labTitle);
|
||||
|
||||
//关联信号
|
||||
connect(this, SIGNAL(titleDblClick()), this, SLOT(titleDblClick()));
|
||||
connect(this, SIGNAL(windowStateChange(bool)), this, SLOT(windowStateChange(bool)));
|
||||
|
||||
//设置样式表
|
||||
QStringList list;
|
||||
list << "#titleBar{background:#BBBBBB;}";
|
||||
list << "#titleBar{border-top-left-radius:8px;border-top-right-radius:8px;}";
|
||||
list << "#widgetMain{border:2px solid #BBBBBB;background:#FFFFFF;}";
|
||||
//list << "#widgetMain{border-bottom-left-radius:8px;border-bottom-right-radius:8px;}";
|
||||
this->setStyleSheet(list.join(""));
|
||||
FlatUI::setScrollBarQss(ui->ram_scrollArea->verticalScrollBar(), 8, 120, 20, "##E5E5E5", "#D0D0D0", "#1ABC9C", "#E74C3C");
|
||||
FlatUI::setScrollBarQss(ui->ram_scrollArea->horizontalScrollBar(), 8, 120, 20, "#E5E5E5", "#D0D0D0", "#1ABC9C", "#E74C3C");
|
||||
FlatUI::setScrollBarQss(ui->flash_scrollArea->verticalScrollBar(), 8, 120, 20, "#E5E5E5", "#D0D0D0", "#1ABC9C", "#E74C3C");
|
||||
FlatUI::setScrollBarQss(ui->flash_scrollArea->horizontalScrollBar(), 8, 120, 20, "#E5E5E5","#D0D0D0", "#1ABC9C", "#E74C3C");
|
||||
|
||||
FlatUI::setScrollBarQss(ui->ram_table->horizontalScrollBar(), 8, 120, 20, "#E5E5E5", "#D0D0D0", "#1ABC9C", "#E74C3C");
|
||||
FlatUI::setScrollBarQss(ui->ram_table->verticalScrollBar(), 8, 120, 20, "#E5E5E5", "#D0D0D0", "#1ABC9C", "#E74C3C");
|
||||
FlatUI::setScrollBarQss(ui->flash_table->horizontalScrollBar(), 8, 120, 20, "#E5E5E5","#D0D0D0", "#1ABC9C", "#E74C3C");
|
||||
FlatUI::setScrollBarQss(ui->flash_table->verticalScrollBar(), 8, 120, 20, "#E5E5E5", "#D0D0D0", "#1ABC9C", "#E74C3C");
|
||||
|
||||
FlatUI::setProgressQss(ui->ram_used_bar, 20,12,16, "#747976", "#1ABC9C");//#FAEC9C",#FFF5E7
|
||||
FlatUI::setProgressQss(ui->flash_used_bar, 20,12,16, "#747976", "#1ABC9C");
|
||||
|
||||
main_window=this;
|
||||
|
||||
|
||||
map_path="P:/AT32_F403A_FreeRTOS/MDK_Project";
|
||||
project_path="P:/AT32_F403A_FreeRTOS/MDK_Project";
|
||||
ui->map_path->setText(map_path);
|
||||
ui->project_path->setText(project_path);
|
||||
|
||||
ram_pieseries=new QPieSeries();
|
||||
flash_pieseries=new QPieSeries();
|
||||
|
||||
cpu= new parse_keil_project(ui->project_path->text());
|
||||
cpu->to_parse_keil_project(ui->project_path->text());
|
||||
if(cpu->getCpu_core_name()!="8051")
|
||||
{
|
||||
map= new parse_map_from_keil( ui->map_path->text(),cpu->IRAM.getBase_addr(),cpu->IRAM.getMax_size(),cpu->IROM.getBase_addr(),cpu->IROM.getMax_size());
|
||||
if(map->to_parse_map_from_keil(ui->map_path->text()))
|
||||
map_calculate_size_by_address(map);
|
||||
|
||||
}else {
|
||||
|
||||
m51 =new parse_m51_from_keil(ui->map_path->text(),cpu->IRAM.getMax_size(),cpu->XRAM.getMax_size(),cpu->IROM.getMax_size());
|
||||
|
||||
|
||||
}
|
||||
|
||||
ram_chart=new QChart();
|
||||
flash_chart=new QChart();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//QChartView
|
||||
|
||||
|
||||
ram_chart->addSeries(ram_pieseries);
|
||||
ram_chart->setTitle("文件内存分布饼图");
|
||||
ram_chart->legend()->hide();
|
||||
// Set the theme to one of the predefined themes
|
||||
ram_chart->setTheme(QChart::ChartThemeQt);
|
||||
ram_chart->setBackgroundBrush(QBrush(Qt::gray));
|
||||
|
||||
flash_chart->addSeries(flash_pieseries);
|
||||
flash_chart->setTitle("文件flash分布饼图");
|
||||
flash_chart->legend()->hide();
|
||||
// Set the theme to one of the predefined themes
|
||||
flash_chart->setTheme(QChart::ChartThemeQt);
|
||||
flash_chart->setBackgroundBrush(QBrush(Qt::gray));
|
||||
|
||||
ui->ram_chart_view->setChart(ram_chart);
|
||||
ui->ram_chart_view->setRubberBand(QChartView::RectangleRubberBand);
|
||||
|
||||
ui->flash_chart_view->setChart(flash_chart);
|
||||
ui->flash_chart_view->setRubberBand(QChartView::RectangleRubberBand);
|
||||
|
||||
update_cpu_info();
|
||||
|
||||
|
||||
if(cpu->getCpu_core_name()!="8051")
|
||||
{
|
||||
update_map_info();
|
||||
}else {
|
||||
update_m51_info();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MainWindow::map_calculate_size_by_address(parse_map_from_keil* map)
|
||||
{
|
||||
|
||||
|
||||
for(auto ram:map->ram_list)
|
||||
{
|
||||
if(ram->getMax_size()>100*1024*1024)
|
||||
{
|
||||
|
||||
uint64_t recent_base=cpu->IRAM.getBase_addr()+cpu->IRAM.getMax_size();
|
||||
|
||||
for(auto recent_ram :map->ram_list)
|
||||
{
|
||||
if(recent_ram->getBase_addr()>ram->getBase_addr())
|
||||
{
|
||||
if(recent_ram->getBase_addr()-ram->getBase_addr()<recent_base-ram->getBase_addr())
|
||||
recent_base=recent_ram->getBase_addr();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ram->setMax_size(recent_base-ram->getBase_addr());
|
||||
}
|
||||
}
|
||||
for(auto flash:map->flash_list)
|
||||
{
|
||||
if(flash->getMax_size()>100*1024*1024)
|
||||
{
|
||||
|
||||
uint64_t recent_base=cpu->IROM.getBase_addr()+cpu->IROM.getMax_size();
|
||||
for(auto recent_flash :map->flash_list)
|
||||
{
|
||||
|
||||
if(recent_flash->getBase_addr()>flash->getBase_addr())
|
||||
{
|
||||
|
||||
if(recent_flash->getBase_addr()-flash->getBase_addr()<recent_base-flash->getBase_addr())
|
||||
recent_base=recent_flash->getBase_addr();
|
||||
|
||||
}
|
||||
}
|
||||
flash->setMax_size(recent_base-flash->getBase_addr());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_btn_set_project_path_clicked()
|
||||
{
|
||||
//获取选择的目录路径
|
||||
QString selectedDir=QFileDialog::getExistingDirectory(this,"选择一个目录","./",QFileDialog::ShowDirsOnly);
|
||||
//若目录路径不为空
|
||||
if (!selectedDir.isEmpty())
|
||||
{
|
||||
//将路径中的斜杠替换为反斜杠
|
||||
selectedDir = selectedDir.replace(QRegExp("\\"), "/");
|
||||
//显示选择的目录路径
|
||||
ui->project_path->setText(selectedDir);
|
||||
ui->map_path->setText(selectedDir);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::set_bar_style(QProgressBar *bar,float per)
|
||||
{
|
||||
if( per/1.0>0.85)
|
||||
{
|
||||
FlatUI::setProgressQss(bar, 20,12,16, "#747976", "#E74C3C");
|
||||
|
||||
}else if( per>0.75)
|
||||
{
|
||||
FlatUI::setProgressQss(bar, 20,12,16, "#747976", "#F9D927");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FlatUI::setProgressQss(bar, 20,12,16, "#747976", "#1ABC9C");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_btn_set_map_path_clicked()
|
||||
{
|
||||
//获取选择的目录路径
|
||||
QString selectedDir=QFileDialog::getExistingDirectory(this,"选择一个目录","./",QFileDialog::ShowDirsOnly);
|
||||
//若目录路径不为空
|
||||
if (!selectedDir.isEmpty())
|
||||
{
|
||||
//将路径中的斜杠替换为反斜杠
|
||||
selectedDir = selectedDir.replace(QRegExp("\\"), "/");
|
||||
//显示选择的目录路径
|
||||
ui->map_path->setText(selectedDir);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_update_info_clicked()
|
||||
{
|
||||
|
||||
|
||||
if(cpu!=nullptr)
|
||||
{
|
||||
delete cpu;
|
||||
cpu=nullptr;
|
||||
}
|
||||
cpu= new parse_keil_project(ui->project_path->text());
|
||||
|
||||
if(cpu->to_parse_keil_project(ui->project_path->text()))
|
||||
update_cpu_info();
|
||||
|
||||
if(cpu->getCpu_core_name()!="8051")
|
||||
{
|
||||
|
||||
if(map!=nullptr)
|
||||
{
|
||||
delete map;
|
||||
map=nullptr;
|
||||
}
|
||||
map= new parse_map_from_keil(ui->map_path->text(),cpu->IRAM.getBase_addr(),cpu->IRAM.getMax_size(),cpu->IROM.getBase_addr(),cpu->IROM.getMax_size());
|
||||
if(map->to_parse_map_from_keil(ui->map_path->text()))
|
||||
map_calculate_size_by_address(map);
|
||||
|
||||
update_map_info();
|
||||
|
||||
}else {
|
||||
|
||||
|
||||
|
||||
if(m51!=nullptr)
|
||||
{
|
||||
delete m51;
|
||||
m51=nullptr;
|
||||
}
|
||||
m51 =new parse_m51_from_keil(ui->map_path->text(),cpu->IRAM.getMax_size(),cpu->XRAM.getMax_size(),cpu->IROM.getMax_size());
|
||||
|
||||
if(m51->to_parse_m51_from_keil(ui->map_path->text()))
|
||||
update_m51_info();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_ram_table_itemSelectionChanged()
|
||||
{
|
||||
QList<QTableWidgetItem*> selectedItems = ui->ram_table->selectedItems();
|
||||
|
||||
|
||||
// Reset all pie slices to not exploded (not highlighted)
|
||||
foreach (QPieSlice* slice, ram_pieseries->slices()) {
|
||||
slice->setExploded(false);
|
||||
slice->setLabelVisible(false);
|
||||
|
||||
}
|
||||
foreach (QTableWidgetItem* item, selectedItems) {
|
||||
int row = item->row();
|
||||
// qDebug() << row;
|
||||
|
||||
QPieSlice *slice = ram_pieseries->slices().at(row);
|
||||
slice->setExploded();//突出这一块
|
||||
slice->setLabelVisible();//设置这一块可见数据
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_flash_table_itemSelectionChanged()
|
||||
{
|
||||
QList<QTableWidgetItem*> selectedItems = ui->flash_table->selectedItems();
|
||||
|
||||
|
||||
// Reset all pie slices to not exploded (not highlighted)
|
||||
foreach (QPieSlice* slice, flash_pieseries->slices()) {
|
||||
slice->setExploded(false);
|
||||
slice->setLabelVisible(false);
|
||||
|
||||
}
|
||||
foreach (QTableWidgetItem* item, selectedItems) {
|
||||
int row = item->row();
|
||||
// qDebug() << row;
|
||||
|
||||
QPieSlice *slice = flash_pieseries->slices().at(row);
|
||||
slice->setExploded();//突出这一块
|
||||
slice->setLabelVisible();//设置这一块可见数据
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MainWindow::update_cpu_info(void)
|
||||
{
|
||||
ui->cpu_name->setTitle(cpu->getCpu_name());
|
||||
ui->cpu_core->setText("单片机核心:"+cpu->getCpu_core_name());
|
||||
ui->cpu_colck->setText(QString().sprintf("最高主频:%.2f MHz",cpu->getCpu_max_clock()/1000000.0));
|
||||
ui->iram->setText(QString().sprintf("内部ram 地址:%#x 容量:%.2f KB",cpu->IRAM.getBase_addr(),cpu->IRAM.getMax_size()/1024.0));
|
||||
ui->flash->setText(QString().sprintf("内部flash 地址:%#x 容量:%.2f KB",cpu->IROM.getBase_addr(),cpu->IROM.getMax_size()/1024.0));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MainWindow::clearLayout(QLayout* layout) {
|
||||
QLayoutItem* item;
|
||||
while ((item = layout->takeAt(0))) {
|
||||
QWidget* widget = item->widget();
|
||||
if (widget) {
|
||||
layout->removeWidget(widget); // 将小部件从布局中移除
|
||||
widget->setParent(nullptr); // 设置父对象为nullptr,避免悬挂指针问题
|
||||
delete widget; // 删除小部件并释放内存
|
||||
}
|
||||
delete item; // 删除布局项
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::update_m51_info(void)
|
||||
{
|
||||
uint64_t ram_all_max_size=0;
|
||||
uint64_t ram_all_used_size=0;
|
||||
uint64_t ram_min_base_addr=m51->ram_list.at(0)->getBase_addr();
|
||||
|
||||
uint64_t flash_all_max_size=0;
|
||||
uint64_t flash_all_used_size=0;
|
||||
uint64_t flash_min_base_addr=m51->flash_list.at(0)->getBase_addr();
|
||||
uint16_t i;
|
||||
|
||||
|
||||
clearLayout(ui->ram_scrollAreaWidgetContents->layout());
|
||||
|
||||
// 移除并释放布局中的所有小部件
|
||||
|
||||
clearLayout(ui->flash_scrollAreaWidgetContents->layout());
|
||||
|
||||
// 移除并释放布局中的所有小部件
|
||||
|
||||
|
||||
for(i=0;i<m51->ram_list.size();i++)
|
||||
{
|
||||
|
||||
ram_all_used_size+=m51->ram_list.at(i)->getUsed_size();
|
||||
ram_all_max_size+=m51->ram_list.at(i)->getMax_size();
|
||||
if(ram_min_base_addr>m51->ram_list.at(0)->getBase_addr())
|
||||
ram_min_base_addr=m51->ram_list.at(i)->getBase_addr();
|
||||
ui->ram_scrollAreaWidgetContents->layout()->addWidget(m51->ram_list.at(i));
|
||||
}
|
||||
|
||||
|
||||
|
||||
ui->ram_addr->setText(QString().sprintf("地址:%#x",ram_min_base_addr));
|
||||
ui->ram_used_bar->setRange(0,ram_all_max_size);
|
||||
ui->ram_used_bar->setValue(ram_all_used_size);
|
||||
ui->ram_remain->setText(QString().sprintf("剩余:%.2f B",ram_all_max_size/10.0-ram_all_used_size/10.0));
|
||||
if(ram_all_max_size/10.0<=1024)
|
||||
{
|
||||
ui->ram_used->setText(QString().sprintf("占用:%.2f B / (%.2f B)",ram_all_used_size/10.0,ram_all_max_size/10.0));
|
||||
}else
|
||||
{
|
||||
ui->ram_used->setText(QString().sprintf("占用:%.2f B / (%.2f KB)",ram_all_used_size/1024.0,ram_all_max_size/10.0/1024.0));
|
||||
}
|
||||
|
||||
set_bar_style(ui->ram_used_bar,ram_all_used_size/1.0/ram_all_max_size/1.0);
|
||||
|
||||
for(i=0;i<m51->flash_list.size();i++)
|
||||
{
|
||||
flash_all_used_size+=m51->flash_list.at(i)->getUsed_size();
|
||||
flash_all_max_size+=m51->flash_list.at(i)->getMax_size();
|
||||
if(flash_min_base_addr>m51->flash_list.at(0)->getBase_addr())
|
||||
flash_min_base_addr=m51->flash_list.at(i)->getBase_addr();
|
||||
ui->flash_scrollAreaWidgetContents->layout()->addWidget(m51->flash_list.at(i));
|
||||
}
|
||||
|
||||
ui->flash_addr->setText(QString().sprintf("地址:%#x",flash_min_base_addr));
|
||||
ui->flash_used_bar->setRange(0,flash_all_max_size);
|
||||
ui->flash_used_bar->setValue(flash_all_used_size);
|
||||
ui->flash_remain->setText(QString().sprintf("剩余:%.2f B",flash_all_max_size/10.0-flash_all_used_size/10.0));
|
||||
if(flash_all_max_size/10.0<=1024)
|
||||
{
|
||||
ui->flash_used->setText(QString().sprintf("占用:%.2f B / (%.2f B)",flash_all_used_size/10.0,flash_all_max_size/10.0));
|
||||
}else
|
||||
{
|
||||
ui->flash_used->setText(QString().sprintf("占用:%.2f B / (%.2f KB)",flash_all_used_size/1024.0,flash_all_max_size/10.0/1024.0));
|
||||
}
|
||||
set_bar_style(ui->flash_used_bar,ram_all_used_size/1.0/ram_all_max_size/1.0);
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::setPieSliceStyle(QPieSlice* slice, qreal percentage, qreal maxPercentage)
|
||||
{
|
||||
|
||||
// Define an array of custom green colors to represent different percentage ranges
|
||||
QColor colors[] = {
|
||||
QColor("#D1FF4D"), // Light Green Yellow
|
||||
QColor("#C0FF3E"), // Greenish Yellow
|
||||
QColor("#ADFF2F"), // Green Yellow
|
||||
QColor("#7CFC00"), // Lawn Green
|
||||
QColor("#00FF00"), // Lime Green
|
||||
QColor("#008000"), // Green
|
||||
QColor("#006400"), // Dark Green
|
||||
};
|
||||
|
||||
// Calculate the relative percentage compared to the maxPercentage
|
||||
qreal relativePercentage = (percentage / maxPercentage) * 100.0;
|
||||
|
||||
// Determine the index of the color based on relative percentage
|
||||
int colorIndex = qMin(int(relativePercentage) / (100 / (sizeof(colors) / sizeof(colors[0]))), sizeof(colors) / sizeof(colors[0]) - 1);
|
||||
|
||||
// Set the color of the slice based on the color index
|
||||
slice->setColor(colors[colorIndex]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::update_map_info(void)
|
||||
{
|
||||
|
||||
uint64_t ram_all_max_size=0;
|
||||
uint64_t ram_all_used_size=0;
|
||||
uint64_t ram_min_base_addr=map->ram_list.at(0)->getBase_addr();
|
||||
|
||||
uint64_t flash_all_max_size=0;
|
||||
uint64_t flash_all_used_size=0;
|
||||
uint64_t flash_min_base_addr=map->flash_list.at(0)->getBase_addr();
|
||||
uint16_t i;
|
||||
|
||||
|
||||
clearLayout(ui->ram_scrollAreaWidgetContents->layout());
|
||||
// // 移除并释放布局中的所有小部件
|
||||
clearLayout(ui->flash_scrollAreaWidgetContents->layout());
|
||||
// // 移除并释放布局中的所有小部件
|
||||
for(uint64_t row_cnt=0;row_cnt<ui->ram_table->rowCount();row_cnt++)
|
||||
{
|
||||
|
||||
ui->ram_table->removeRow(row_cnt);
|
||||
}
|
||||
|
||||
ram_pieseries->clear();
|
||||
|
||||
for(uint64_t row_cnt=0;row_cnt<ui->flash_table->rowCount();row_cnt++)
|
||||
{
|
||||
ui->flash_table->removeRow(row_cnt);
|
||||
}
|
||||
|
||||
flash_pieseries->clear();
|
||||
|
||||
|
||||
|
||||
for(i=0;i<map->ram_list.size();i++)
|
||||
{
|
||||
|
||||
ram_all_used_size+=map->ram_list.at(i)->getUsed_size();
|
||||
ram_all_max_size+=map->ram_list.at(i)->getMax_size();
|
||||
if(ram_min_base_addr>map->ram_list.at(0)->getBase_addr())
|
||||
ram_min_base_addr=map->ram_list.at(i)->getBase_addr();
|
||||
ui->ram_scrollAreaWidgetContents->layout()->addWidget(map->ram_list.at(i));
|
||||
}
|
||||
|
||||
|
||||
|
||||
ui->ram_addr->setText(QString().sprintf("地址:%#x",ram_min_base_addr));
|
||||
ui->ram_used_bar->setRange(0,ram_all_max_size);
|
||||
ui->ram_used_bar->setValue(ram_all_used_size);
|
||||
ui->ram_remain->setText(QString().sprintf("剩余:%llu B",ram_all_max_size-ram_all_used_size));
|
||||
if(ram_all_max_size<=1024*1024)
|
||||
{
|
||||
ui->ram_used->setText(QString().sprintf("占用:%.2f KB / (%.2f KB)",ram_all_used_size/1024.0,ram_all_max_size/1024.0));
|
||||
}else
|
||||
{
|
||||
ui->ram_used->setText(QString().sprintf("占用:%.4f MB / (%.4f MB)",ram_all_used_size/1024.0/1024.0,ram_all_max_size/1024.0/1024.0));
|
||||
}
|
||||
|
||||
set_bar_style(ui->ram_used_bar,ram_all_used_size/1.0/ram_all_max_size/1.0);
|
||||
|
||||
|
||||
for(i=0;i<map->flash_list.size();i++)
|
||||
{
|
||||
flash_all_used_size+=map->flash_list.at(i)->getUsed_size();
|
||||
flash_all_max_size+=map->flash_list.at(i)->getMax_size();
|
||||
if(flash_min_base_addr>map->flash_list.at(0)->getBase_addr())
|
||||
flash_min_base_addr=map->flash_list.at(i)->getBase_addr();
|
||||
ui->flash_scrollAreaWidgetContents->layout()->addWidget(map->flash_list.at(i));
|
||||
}
|
||||
|
||||
ui->flash_addr->setText(QString().sprintf("地址:%#x",flash_min_base_addr));
|
||||
ui->flash_used_bar->setRange(0,flash_all_max_size);
|
||||
ui->flash_used_bar->setValue(flash_all_used_size);
|
||||
ui->flash_remain->setText(QString().sprintf("剩余:%llu B",flash_all_max_size-flash_all_used_size));
|
||||
if(flash_all_max_size<=1024*1024)
|
||||
{
|
||||
ui->flash_used->setText(QString().sprintf("占用:%.2f KB / (%.2f KB)",flash_all_used_size/1024.0,flash_all_max_size/1024.0));
|
||||
}else
|
||||
{
|
||||
ui->flash_used->setText(QString().sprintf("占用:%.4f MB / (%.4f MB)",flash_all_used_size/1024.0/1024.0,flash_all_max_size/1024.0/1024.0));
|
||||
}
|
||||
|
||||
set_bar_style(ui->flash_used_bar,ram_all_used_size/1.0/ram_all_max_size/1.0);
|
||||
|
||||
|
||||
|
||||
|
||||
QList <image_item_t*> info_lsit= map->getInfo_list();
|
||||
uint64_t all_ram_size = map->getAll_ram_size();
|
||||
uint64_t all_flash_size =map->getAll_flash_size();
|
||||
uint64_t ram_row=0;
|
||||
uint64_t flash_row=0;
|
||||
for(auto item:info_lsit)
|
||||
{
|
||||
if(item->RW_Data.toUInt()+item->ZI_Data.toUInt()!=0)
|
||||
{
|
||||
writeTableData(ram_table,ram_row,0,item->Object_Name);
|
||||
writeTableData(ram_table,ram_row,1,QString::number(item->RW_Data.toUInt()+item->ZI_Data.toUInt()));
|
||||
writeTableData(ram_table,ram_row,3,item->RW_Data);
|
||||
writeTableData(ram_table,ram_row,4,item->ZI_Data);
|
||||
all_ram_size+=item->RW_Data.toUInt()+item->ZI_Data.toUInt();
|
||||
ram_row++;
|
||||
}
|
||||
|
||||
if(item->Code.toUInt()+item->RO_Data.toUInt()+item->RW_Data.toUInt()!=0)
|
||||
{
|
||||
|
||||
|
||||
writeTableData(flash_table,flash_row,0,item->Object_Name);
|
||||
writeTableData(flash_table,flash_row,1,QString::number(item->Code.toUInt()+item->RO_Data.toUInt()+item->RW_Data.toUInt()));
|
||||
writeTableData(flash_table,flash_row,3,item->Code);
|
||||
writeTableData(flash_table,flash_row,4,item->RO_Data);
|
||||
writeTableData(flash_table,flash_row,5,item->RW_Data);
|
||||
all_flash_size+=item->Code.toUInt()+item->RO_Data.toUInt()+item->RW_Data.toUInt();
|
||||
flash_row++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ui->ram_per->setTitle(QString().sprintf("used_ram=RW+ZI=%llu",all_ram_size));
|
||||
ui->flash_per->setTitle(QString().sprintf("used_flash=RW+Code+RO=%llu",all_flash_size));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for(uint64_t row_cnt=0;row_cnt<ui->ram_table->rowCount();row_cnt++)
|
||||
{
|
||||
writeTableData(ram_table,row_cnt,2,QString().sprintf("%05.2f%%",ui->ram_table->item(row_cnt,1)->text().toUInt()*100.0/all_ram_size/1.0));
|
||||
}
|
||||
|
||||
for(uint64_t row_cnt=0;row_cnt<ui->flash_table->rowCount();row_cnt++)
|
||||
{
|
||||
writeTableData(flash_table,row_cnt,2,QString().sprintf("%05.2f%%",ui->flash_table->item(row_cnt,1)->text().toUInt()*100.0/all_flash_size/1.0));
|
||||
}
|
||||
|
||||
ui->ram_table->sortByColumn(2,Qt::SortOrder::DescendingOrder);
|
||||
ui->flash_table->sortByColumn(2,Qt::SortOrder::DescendingOrder);
|
||||
|
||||
|
||||
|
||||
for(uint64_t row_cnt=0;row_cnt<ui->ram_table->rowCount();row_cnt++)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
QPieSlice *slice =ram_pieseries->append(ui->ram_table->item(row_cnt,0)->text()+":"+ui->ram_table->item(row_cnt,2)->text(),ui->ram_table->item(row_cnt,1)->text().toUInt());
|
||||
|
||||
setPieSliceStyle(slice,ui->ram_table->item(row_cnt,2)->text().split("%")[0].toFloat(),ui->ram_table->item(0,2)->text().split("%")[0].toFloat());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
for(uint64_t row_cnt=0;row_cnt<ui->flash_table->rowCount();row_cnt++)
|
||||
{
|
||||
QPieSlice *slice =flash_pieseries->append(ui->flash_table->item(row_cnt,0)->text()+":"+ui->flash_table->item(row_cnt,2)->text(),ui->flash_table->item(row_cnt,1)->text().toUInt());
|
||||
setPieSliceStyle(slice,ui->flash_table->item(row_cnt,2)->text().split("%")[0].toFloat(),ui->flash_table->item(0,2)->text().split("%")[0].toFloat());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QString MainWindow::readTableData(ui_table_t table,int row, int column)
|
||||
{
|
||||
QString data;
|
||||
QTableWidget* tableWidget ;
|
||||
if( table==ram_table)tableWidget=ui->ram_table;
|
||||
else tableWidget=ui->flash_table;
|
||||
|
||||
if (row < tableWidget->rowCount() && column <tableWidget->columnCount()) {
|
||||
QTableWidgetItem *item =tableWidget->item(row, column);
|
||||
if (item) {
|
||||
data = item->text();
|
||||
// qDebug() << "Data at (" << row << ", " << column << "): " << data;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::writeTableData(ui_table_t table,int row, int column, const QString &data)
|
||||
{
|
||||
|
||||
|
||||
QTableWidget* tableWidget=nullptr;
|
||||
if (table == ram_table)
|
||||
{
|
||||
|
||||
tableWidget=ui->ram_table;
|
||||
|
||||
}
|
||||
else if (table == flash_table)
|
||||
{
|
||||
tableWidget = ui->flash_table;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Invalid table specified.";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (row >= tableWidget->rowCount())
|
||||
{
|
||||
tableWidget->setRowCount(row + 1);
|
||||
}
|
||||
if (column >= tableWidget->columnCount())
|
||||
{
|
||||
tableWidget->setColumnCount(column + 1);
|
||||
}
|
||||
|
||||
if (!tableWidget->item(row, column))
|
||||
{
|
||||
QTableWidgetItem *newItem = new QTableWidgetItem(data);
|
||||
tableWidget->setItem(row, column, newItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
tableWidget->item(row, column)->setText(data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MainWindow::titleDblClick()
|
||||
{
|
||||
on_btnMenu_Max_clicked();
|
||||
}
|
||||
|
||||
void MainWindow::windowStateChange(bool max)
|
||||
{
|
||||
ui->btnMenu_Max->setText(max ? "还原" : "最大");
|
||||
}
|
||||
|
||||
void MainWindow::on_btnMenu_Min_clicked()
|
||||
{
|
||||
#ifdef Q_OS_MACOS
|
||||
this->setWindowFlags(this->windowFlags() & ~Qt::FramelessWindowHint);
|
||||
#endif
|
||||
this->showMinimized();
|
||||
}
|
||||
|
||||
void MainWindow::on_btnMenu_Max_clicked()
|
||||
{
|
||||
if (this->isMaximized()) {
|
||||
this->showNormal();
|
||||
ui->btnMenu_Max->setText("最大");
|
||||
} else {
|
||||
this->showMaximized();
|
||||
ui->btnMenu_Max->setText("还原");
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_btnMenu_Close_clicked()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
||||
void MainWindow::on_gitee_index_clicked()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl("https://gitee.com/nikolan")); // Change the URL to the desired webpage
|
||||
|
||||
}
|
68
mainwindow.h
Normal file
68
mainwindow.h
Normal file
@ -0,0 +1,68 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include "framelessmainwindow.h"
|
||||
|
||||
#include "parse_keil_project.h"
|
||||
#include "parse_map_from_keil.h"
|
||||
#include "parse_m51_from_keil.h"
|
||||
|
||||
#include <QtCharts>
|
||||
extern QString project_path;
|
||||
extern QString map_path;
|
||||
extern bool only_printf;
|
||||
|
||||
QT_CHARTS_USE_NAMESPACE
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
typedef enum{ram_table,flash_table}ui_table_t;
|
||||
class MainWindow : public FramelessMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
void setPieSliceStyle(QPieSlice* slice, qreal percentage, qreal maxPercentage);
|
||||
void set_bar_style(QProgressBar *bar,float per);
|
||||
void update_cpu_info(void);
|
||||
void update_map_info(void);
|
||||
void update_m51_info(void);
|
||||
QString readTableData(ui_table_t table,int row, int column);
|
||||
void writeTableData(ui_table_t table,int row, int column, const QString &data);
|
||||
void map_calculate_size_by_address(parse_map_from_keil* map);
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
QPieSeries *ram_pieseries=nullptr;
|
||||
QPieSeries *flash_pieseries=nullptr;
|
||||
QChart* ram_chart=nullptr;
|
||||
QChart* flash_chart=nullptr;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void clearLayout(QLayout* layout);
|
||||
parse_keil_project* cpu=nullptr;
|
||||
parse_map_from_keil* map=nullptr;
|
||||
parse_m51_from_keil* m51=nullptr;
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
void titleDblClick();
|
||||
void windowStateChange(bool max);
|
||||
|
||||
private slots:
|
||||
void on_btnMenu_Min_clicked();
|
||||
void on_btnMenu_Max_clicked();
|
||||
void on_btnMenu_Close_clicked();
|
||||
void on_btn_set_project_path_clicked();
|
||||
void on_btn_set_map_path_clicked();
|
||||
void on_update_info_clicked();
|
||||
void on_ram_table_itemSelectionChanged();
|
||||
void on_flash_table_itemSelectionChanged();
|
||||
void on_gitee_index_clicked();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
965
mainwindow.ui
Normal file
965
mainwindow.ui
Normal file
@ -0,0 +1,965 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color:#3f3f3f;
|
||||
background: #ECF0F1;</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="titleBar" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color:#ffffff;
|
||||
background:#34495E;
|
||||
border-top-left-radius:8px;
|
||||
border-top-right-radius:8px;</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="R.qrc">
|
||||
<normaloff>:/KDA_Logo.ico</normaloff>:/KDA_Logo.ico</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labTitle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>一个极客开源::keil开发助手</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetMenu" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnMenu_Min">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>ArrowCursor</cursorShape>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>最小化</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
border-style: none;
|
||||
padding: 8px;
|
||||
border-radius: 5px;
|
||||
color: #FFFFFF;
|
||||
background: #3498DB;
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
color: #FFF5E7;
|
||||
background: #2E86C1;
|
||||
}
|
||||
|
||||
QPushButton:pressed {
|
||||
color: #F5A996;
|
||||
background: #1B4F72;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QPushButton:disabled{
|
||||
background-color: #34495E;
|
||||
border-color: #D6D6D6;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>最小</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnMenu_Max">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton{border-style:none;padding:8px;border-radius:5px;color:#E6F8F5;background:#1ABC9C;}
|
||||
QPushButton:hover{color:#FFFFFF;background:#2EE1C1;}
|
||||
QPushButton:pressed{color:#A7EEE6;background:#16A086;}
|
||||
|
||||
QPushButton:disabled{
|
||||
background-color: #34495E;
|
||||
border-color: #D6D6D6;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>最大</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnMenu_Close">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>ArrowCursor</cursorShape>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>关闭</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton{border-style:none;padding:8px;border-radius:5px;color:#FFFFFF;background:#E74C3C;}
|
||||
QPushButton:hover{color:#FFF5E7;background:#EC7064;}
|
||||
QPushButton:pressed{color:#F5A996;background:#DC2D1A;}
|
||||
|
||||
|
||||
QPushButton:disabled{
|
||||
background-color: #34495E;
|
||||
border-color: #D6D6D6;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>关闭</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="setting">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>手动操作</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="btn_set_project_path">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
border-style: none;
|
||||
padding: 8px;
|
||||
border-radius: 5px;
|
||||
color: #FFFFFF;
|
||||
background: #3498DB;
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
color: #FFF5E7;
|
||||
background: #2E86C1;
|
||||
}
|
||||
|
||||
QPushButton:pressed {
|
||||
color: #F5A996;
|
||||
background: #1B4F72;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QPushButton:disabled{
|
||||
background-color: #34495E;
|
||||
border-color: #D6D6D6;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择目录</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_project_path">
|
||||
<property name="text">
|
||||
<string>工程路径:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="project_path"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="btn_set_map_path">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
border-style: none;
|
||||
padding: 8px;
|
||||
border-radius: 5px;
|
||||
color: #FFFFFF;
|
||||
background: #3498DB;
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
color: #FFF5E7;
|
||||
background: #2E86C1;
|
||||
}
|
||||
|
||||
QPushButton:pressed {
|
||||
color: #F5A996;
|
||||
background: #1B4F72;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QPushButton:disabled{
|
||||
background-color: #34495E;
|
||||
border-color: #D6D6D6;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择目录</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_map_path">
|
||||
<property name="text">
|
||||
<string> map文件路径:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="map_path"/>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="update_info">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton{border-style:none;padding:8px;border-radius:5px;color:#E6F8F5;background:#1ABC9C;}
|
||||
QPushButton:hover{color:#FFFFFF;background:#2EE1C1;}
|
||||
QPushButton:pressed{color:#A7EEE6;background:#16A086;}
|
||||
|
||||
QPushButton:disabled{
|
||||
background-color: #34495E;
|
||||
border-color: #D6D6D6;
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>手动更新数据</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>6</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">
|
||||
QTabWidget::pane {
|
||||
|
||||
background-color:#34495E;
|
||||
border-top: 2px solid #C2C7CB;
|
||||
/* position: absolute;
|
||||
top: -0.5em; */
|
||||
border-color: #9B9B9B;
|
||||
color: rgb(255, 255, 255);
|
||||
|
||||
}
|
||||
|
||||
|
||||
QTabWidget::tab-bar {
|
||||
|
||||
background-color: #34495E;
|
||||
color: rgb(255, 255, 255);
|
||||
/* alignment: center; */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
QTabBar {
|
||||
background-color: #34495E;
|
||||
color: rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
|
||||
|
||||
background-color:#2EE1C1;
|
||||
color: rgb(255, 255, 255);
|
||||
|
||||
|
||||
}
|
||||
|
||||
QTabBar::tab:!selected{
|
||||
|
||||
background-color:#34495E;
|
||||
color: rgb(255, 255, 255);
|
||||
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="bulid_info">
|
||||
<attribute name="title">
|
||||
<string>构建后信息</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="cpu_name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>mcu_name</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="cpu_colck">
|
||||
<property name="text">
|
||||
<string>最高主频:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="flash">
|
||||
<property name="text">
|
||||
<string>内部flash 大小:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="iram">
|
||||
<property name="text">
|
||||
<string>内部ram 大小:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="cpu_core">
|
||||
<property name="text">
|
||||
<string>核心:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>3</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="ram_all">
|
||||
<property name="title">
|
||||
<string>按map文件识别的ram</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QScrollArea" name="ram_scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="ram_scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>360</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="ram_name">
|
||||
<property name="title">
|
||||
<string> all_ram</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="ram_addr">
|
||||
<property name="text">
|
||||
<string>地址:0xxxxxx</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="ram_used_bar">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="ram_used">
|
||||
<property name="text">
|
||||
<string>占用:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="ram_remain">
|
||||
<property name="text">
|
||||
<string>还剩:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="flash_all">
|
||||
<property name="title">
|
||||
<string>按map文件识别的flash</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="1" column="0">
|
||||
<widget class="QScrollArea" name="flash_scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="flash_scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>360</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="flash_name">
|
||||
<property name="title">
|
||||
<string>all_flash</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="flash_addr">
|
||||
<property name="text">
|
||||
<string>地址:0xxxxxx</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="flash_used_bar">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="flash_used">
|
||||
<property name="text">
|
||||
<string>占用:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="flash_remain">
|
||||
<property name="text">
|
||||
<string>还剩:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>ram占比</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="ram_per">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>project::xxx cup:xxxx</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTableWidget" name="ram_table">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>文件名</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>占用ram大小B</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>占用ram比例%</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>RW</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>ZI</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="ram_pie">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>2</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string> 占用饼图</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="0" column="0">
|
||||
<widget class="QChartView" name="ram_chart_view"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string> flash占比</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="flash_per">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>project::xxx cup:xxxx</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTableWidget" name="flash_table">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>文件名</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>占用flash大小B</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>占用flash比例%</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Code</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>RO</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>RW</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="flash_pie">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>2</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string> 占用饼图</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_13">
|
||||
<item row="0" column="0">
|
||||
<widget class="QChartView" name="flash_chart_view"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string> 更多</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QTextBrowser" name="textBrowser_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>4</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">这是一个开源项目,基于GPLv2开源协议。</p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">你可以通过来gitee开源仓库地址,</p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">来反馈BUG或者提供优化代码来帮助维护这个项目,</p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">或者给予建议或者告诉作者你想要的功能。</p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">参与了代码的奉献,实现某些功能或优化了某些代码,</p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">会更新到readme的奉献者名单。</p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">或者能力赞助该项目开发的,</p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">会更新到readme赞助者名单。</p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">该软件将永久免费,开源不易,谢谢大家的支持,</p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">你的支持是我更新维护项目的动力。</p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">留言:ageek_nikola </p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">邮箱:2503865771@qq.com</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="ageek">
|
||||
<property name="title">
|
||||
<string>一个极客ageek开源</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="icon">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="R.qrc">
|
||||
<normaloff>:/KDA_Logo.ico</normaloff>:/KDA_Logo.ico</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="gitee_index">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="R.qrc">
|
||||
<normaloff>:/gitee.png</normaloff>:/gitee.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>60</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>点击以上图标跳转到gitee开源地址</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QTextBrowser" name="textBrowser">
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">KDA</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">keil_development_assistant</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">keil开发助手</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#0055ff;">主要解决的问题:</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#0055ff;">无需反复翻查map文件,</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#0055ff;">让你的嵌入式软件能更好的进行优化</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#00aa00;">主要实现的功能:</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#00aa00;">- 分析ram和flash占用百分比</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#00aa00;">- 分析已使用的ram和flash的各文件占比</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QChartView</class>
|
||||
<extends>QGraphicsView</extends>
|
||||
<header location="global">qchartview.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="R.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
110
only_run_by_file.cpp
Normal file
110
only_run_by_file.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "only_run_by_file.h"
|
||||
|
||||
only_run_by_file::only_run_by_file(QObject *parent) : QObject(parent),
|
||||
runFileName("run"),
|
||||
closeFileName("close")
|
||||
{
|
||||
|
||||
|
||||
|
||||
// 如果 run 文件已经存在,则删除
|
||||
if (QFile::exists(runFileName)) {
|
||||
QFile::remove(runFileName);
|
||||
|
||||
// 检测 close 文件是否存在的定时器
|
||||
closeTimer = new QTimer(this);
|
||||
connect(closeTimer, &QTimer::timeout, this, &only_run_by_file::checkCloseFile);
|
||||
closeTimer->start(300); // 每 300 毫秒执行一次检测
|
||||
}else
|
||||
createRunFile();
|
||||
|
||||
|
||||
|
||||
|
||||
// 检测 run 文件是否存在的定时器
|
||||
timer = new QTimer(this);
|
||||
connect(timer, &QTimer::timeout, this, &only_run_by_file::checkRunFile);
|
||||
timer->start(800); // 每 800 毫秒执行一次检测
|
||||
}
|
||||
|
||||
void only_run_by_file::createCloseFile()
|
||||
{
|
||||
// 创建 close 文件
|
||||
QFile file(closeFileName);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
file.close();
|
||||
}
|
||||
|
||||
void only_run_by_file::createRunFile()
|
||||
{
|
||||
// 创建 run 文件
|
||||
QFile file(runFileName);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
file.close();
|
||||
}
|
||||
|
||||
void only_run_by_file::deleteCloseFile()
|
||||
{
|
||||
// 如果 close 文件已经存在,则删除
|
||||
if (QFile::exists(closeFileName)) {
|
||||
QFile::remove(closeFileName);
|
||||
}
|
||||
|
||||
}
|
||||
void only_run_by_file::deleteRunFile()
|
||||
{
|
||||
// 如果 run 文件已经存在,则删除
|
||||
if (QFile::exists(runFileName)) {
|
||||
QFile::remove(runFileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void only_run_by_file::checkRunFile()
|
||||
{
|
||||
// 检测 run 文件是否存在
|
||||
if (!QFile::exists(runFileName)) {
|
||||
// 文件不存在,采集关闭操作并创建 close 文件
|
||||
deleteCloseFile();
|
||||
// 创建 close 文件
|
||||
createCloseFile();
|
||||
emit runFileDeleted();
|
||||
}
|
||||
}
|
||||
|
||||
void only_run_by_file::checkCloseFile()
|
||||
{
|
||||
static uint8_t cnt=0;
|
||||
|
||||
if(cnt<3)
|
||||
{
|
||||
|
||||
cnt++;
|
||||
// 检测 close 文件是否存在
|
||||
if (QFile::exists(closeFileName)) {
|
||||
// 发出信号,通知检测到 close 文件
|
||||
closeTimer->stop();
|
||||
// 如果 close 文件已经存在,则删除
|
||||
deleteCloseFile();
|
||||
// 创建 run 文件
|
||||
createRunFile();
|
||||
|
||||
|
||||
|
||||
emit closeFileDetected();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}else
|
||||
{
|
||||
cnt=0;
|
||||
// 如果 close 文件已经存在,则删除
|
||||
deleteCloseFile();
|
||||
// 创建 run 文件
|
||||
createRunFile();
|
||||
emit closeFileDetected();
|
||||
}
|
||||
|
||||
}
|
32
only_run_by_file.h
Normal file
32
only_run_by_file.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef ONLY_RUN_BY_FILE_H
|
||||
#define ONLY_RUN_BY_FILE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
|
||||
class only_run_by_file : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit only_run_by_file(QObject *parent = nullptr);
|
||||
|
||||
private:
|
||||
const QString runFileName;
|
||||
const QString closeFileName;
|
||||
|
||||
void createCloseFile();
|
||||
void createRunFile();
|
||||
void deleteCloseFile();
|
||||
void deleteRunFile();
|
||||
QTimer* closeTimer;
|
||||
QTimer* timer ;
|
||||
signals:
|
||||
void runFileDeleted();
|
||||
void closeFileDetected();
|
||||
|
||||
public slots:
|
||||
void checkRunFile();
|
||||
void checkCloseFile();
|
||||
};
|
||||
#endif // ONLY_RUN_BY_FILE_H
|
260
parse_keil_project.cpp
Normal file
260
parse_keil_project.cpp
Normal file
@ -0,0 +1,260 @@
|
||||
#include "parse_keil_project.h"
|
||||
|
||||
|
||||
#include <QFile>
|
||||
#include <QDomDocument>
|
||||
#include <Qtxml>
|
||||
#include <QDebug>
|
||||
#include <qxmlstream.h>
|
||||
|
||||
|
||||
#include "find_path.h"
|
||||
|
||||
|
||||
QString parse_keil_project::find_project_path(const QString& dir_path)
|
||||
{
|
||||
|
||||
return find_path::find_file_path(dir_path,".uvproj");
|
||||
|
||||
}
|
||||
|
||||
parse_keil_project::parse_keil_project(QString path)
|
||||
{
|
||||
|
||||
|
||||
|
||||
IRAM.setName("IRAM");
|
||||
XRAM.setName("XRAM");
|
||||
IROM.setName("IROM");
|
||||
|
||||
// to_parse_keil_project(path);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool parse_keil_project::to_parse_keil_project(QString path)
|
||||
{
|
||||
project_path=path;
|
||||
QString file_path;
|
||||
|
||||
if(path.contains(".uvproj"))
|
||||
{
|
||||
parse_project_file(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
file_path=find_project_path(project_path);
|
||||
qDebug()<<file_path;
|
||||
if(file_path.length()<3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
parse_project_file(file_path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool parse_keil_project::parse_info_item_max_clock(const QString& info_item)
|
||||
{
|
||||
|
||||
QStringList info_list;
|
||||
uint64_t data;
|
||||
bool is_int;
|
||||
uint8_t data_cnt=0;
|
||||
info_list= info_item.split("(");//按"\""分割
|
||||
cpu_max_clock=info_list[1].toInt(&is_int,10);
|
||||
|
||||
|
||||
}
|
||||
|
||||
QString parse_keil_project::getCpu_core_name() const
|
||||
{
|
||||
return cpu_core_name;
|
||||
}
|
||||
|
||||
uint64_t parse_keil_project::getCpu_max_clock() const
|
||||
{
|
||||
return cpu_max_clock;
|
||||
}
|
||||
|
||||
QString parse_keil_project::getProject_path() const
|
||||
{
|
||||
return project_path;
|
||||
}
|
||||
|
||||
void parse_keil_project::setProject_path(const QString &value)
|
||||
{
|
||||
project_path = value;
|
||||
}
|
||||
|
||||
QString parse_keil_project::getCpu_name() const
|
||||
{
|
||||
return cpu_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool parse_keil_project::parse_info_item_core_name(const QString& info_item)
|
||||
{
|
||||
|
||||
QStringList info_list;
|
||||
uint64_t data;
|
||||
bool is_int;
|
||||
uint8_t data_cnt=0;
|
||||
info_list= info_item.split("\"");//按"\""分割
|
||||
cpu_core_name=info_list[1];
|
||||
|
||||
}
|
||||
|
||||
bool parse_keil_project::parse_info_item_storage(const QString& info_item,use_percentage_bar& storage )
|
||||
{
|
||||
QStringList info_list;
|
||||
uint64_t data;
|
||||
bool is_int;
|
||||
uint8_t data_cnt=0;
|
||||
QString sp_char=",";
|
||||
|
||||
if(info_item.contains("-"))
|
||||
sp_char="-";
|
||||
|
||||
info_list= info_item.split("(");//按"("分割
|
||||
info_list= info_list[1].split(sp_char);//按","或者"-"分割
|
||||
|
||||
data_cnt==0;
|
||||
for(auto info:info_list)
|
||||
{
|
||||
info.remove(QChar(','), Qt::CaseInsensitive);//去除","
|
||||
info.remove(QChar(')'), Qt::CaseInsensitive);//去除")"
|
||||
info.remove(QChar('x'), Qt::CaseInsensitive);//去除"0x"的'x'
|
||||
data=info.toInt(&is_int,16);//转16进制
|
||||
|
||||
if(is_int)//判断是否是16进制整数
|
||||
{
|
||||
if(data_cnt==0)//第一个16进制数是base地址
|
||||
{
|
||||
storage.setBase_addr(data);
|
||||
data_cnt++;
|
||||
|
||||
}else//第二个十六进制数是 max容量大小
|
||||
{
|
||||
storage.setMax_size(data);
|
||||
data_cnt=0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
qDebug()<<QString().sprintf("%s base:%#x size:%.2f KB",storage.getName().toStdString().data(), storage.getBase_addr(),storage.getMax_size()/1024.0);
|
||||
|
||||
}
|
||||
|
||||
bool parse_keil_project::parse_cpu_info(const QString& cpu_info)
|
||||
{
|
||||
|
||||
QStringList cpu_info_list = cpu_info.split(")");
|
||||
|
||||
|
||||
for(auto info_item:cpu_info_list)
|
||||
{
|
||||
// qDebug()<<info_item;
|
||||
if(info_item.contains("IRAM"))//包含"IRAM"字段
|
||||
{
|
||||
parse_info_item_storage(info_item,IRAM);
|
||||
}
|
||||
else if(info_item.contains("XRAM"))//包含"XRAM"字段
|
||||
{
|
||||
parse_info_item_storage(info_item,XRAM);
|
||||
}
|
||||
else if(info_item.contains("IROM"))
|
||||
{
|
||||
parse_info_item_storage(info_item,IROM);
|
||||
}
|
||||
else if(info_item.contains("CPUTYPE"))
|
||||
{
|
||||
parse_info_item_core_name(info_item);
|
||||
qDebug()<<"core:"<<cpu_core_name;
|
||||
}
|
||||
else if(info_item.contains("CLOCK"))
|
||||
{
|
||||
parse_info_item_max_clock(info_item);
|
||||
qDebug()<<"main_clock:"<<cpu_max_clock<<"MHz";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool parse_keil_project::parse_project_file(QString path)
|
||||
{
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
qDebug()<<"open fail"<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
QXmlStreamReader reader(&file);
|
||||
while(!reader.atEnd())
|
||||
{
|
||||
|
||||
if(reader.isStartElement())
|
||||
{
|
||||
// qDebug()<<"<"<<reader.name();
|
||||
|
||||
if("Cpu"==reader.name())
|
||||
{
|
||||
|
||||
parse_cpu_info(reader.readElementText());
|
||||
|
||||
}else if("Device"==reader.name())
|
||||
{
|
||||
|
||||
cpu_name=(reader.readElementText());
|
||||
|
||||
}else if("ToolsetName" ==reader.name())
|
||||
{
|
||||
|
||||
if(reader.readElementText().contains("MCS-51"))
|
||||
cpu_core_name="8051";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
if(reader.isEndElement())
|
||||
{
|
||||
// qDebug()<<">"<<reader.name();
|
||||
}
|
||||
|
||||
reader.readNext();
|
||||
|
||||
|
||||
}
|
||||
if (reader.hasError())
|
||||
{
|
||||
qDebug()<<reader.errorString();
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
}
|
51
parse_keil_project.h
Normal file
51
parse_keil_project.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef PARSE_KEIL_PROJECT_H
|
||||
#define PARSE_KEIL_PROJECT_H
|
||||
|
||||
#include <QString>
|
||||
#include <use_percentage_bar.h>
|
||||
|
||||
|
||||
class parse_keil_project
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
parse_keil_project(QString path);
|
||||
bool to_parse_keil_project(QString path);
|
||||
QString find_project_path(const QString& dir_path);
|
||||
bool parse_project_file(QString path);
|
||||
bool parse_cpu_info(const QString& cpu_info);
|
||||
|
||||
bool parse_info_item_storage(const QString& info_item,use_percentage_bar& storage );
|
||||
bool parse_info_item_core_name(const QString& info_item);
|
||||
bool parse_info_item_max_clock(const QString& info_item);
|
||||
|
||||
QString getCpu_core_name() const;
|
||||
|
||||
uint64_t getCpu_max_clock() const;
|
||||
|
||||
QString getProject_path() const;
|
||||
void setProject_path(const QString &value);
|
||||
|
||||
use_percentage_bar IRAM;
|
||||
use_percentage_bar IROM;
|
||||
use_percentage_bar XRAM;
|
||||
|
||||
|
||||
QString getCpu_name() const;
|
||||
|
||||
private:
|
||||
QString project_path;
|
||||
// uint64_t iram_base;
|
||||
// uint64_t xram_base;
|
||||
// uint64_t irom_base;
|
||||
// uint64_t iram_size;
|
||||
// uint64_t xram_size;
|
||||
// uint64_t irom_size;
|
||||
QString cpu_name;
|
||||
QString cpu_core_name;
|
||||
uint64_t cpu_max_clock;
|
||||
|
||||
};
|
||||
|
||||
#endif // PARSE_KEIL_PROJECT_H
|
180
parse_m51_from_keil.cpp
Normal file
180
parse_m51_from_keil.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
#include "parse_m51_from_keil.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QDomDocument>
|
||||
#include "find_path.h"
|
||||
|
||||
#include <Qdebug>
|
||||
|
||||
parse_m51_from_keil::parse_m51_from_keil(QString path,uint64_t iram_max_size,uint64_t xram_max_size,
|
||||
uint64_t irom_max_size)
|
||||
{
|
||||
|
||||
iram_max=iram_max_size;
|
||||
xram_max=xram_max_size;
|
||||
irom_max=irom_max_size;
|
||||
|
||||
//to_parse_m51_from_keil(path);
|
||||
}
|
||||
|
||||
bool parse_m51_from_keil::to_parse_m51_from_keil(QString path)
|
||||
{
|
||||
|
||||
|
||||
QString file_path=find_m51_path(path);
|
||||
qDebug()<<file_path;
|
||||
if(file_path.length()>3){
|
||||
|
||||
parse_m51_file(file_path);
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
qDebug()<<"路径错误";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString parse_m51_from_keil::find_m51_path(const QString &dir_path)
|
||||
{
|
||||
|
||||
|
||||
QString m51_file_path;
|
||||
m51_file_path=find_path::find_file_path(dir_path,".m51");
|
||||
if(m51_file_path.length()<3)
|
||||
m51_file_path=find_path::find_file_path(dir_path,".M51");
|
||||
|
||||
return m51_file_path;
|
||||
}
|
||||
|
||||
bool parse_m51_from_keil::parse_m51_file(QString path)
|
||||
{
|
||||
QFile file(path);
|
||||
|
||||
iram=new use_percentage_bar(nullptr);
|
||||
xram=new use_percentage_bar(nullptr);
|
||||
irom=new use_percentage_bar(nullptr);
|
||||
|
||||
|
||||
iram->setName("iram");
|
||||
iram->setStorage(mc8051);
|
||||
iram->setBase_addr(0);
|
||||
xram->setName("xram");
|
||||
xram->setStorage(mc8051);
|
||||
xram->setBase_addr(0);
|
||||
xram->setMax_size(0);
|
||||
|
||||
irom->setName("irom");
|
||||
irom->setStorage(mc8051);
|
||||
irom->setBase_addr(0);
|
||||
|
||||
iram->setMax_size(iram_max*10.0);
|
||||
|
||||
xram->setMax_size(xram_max*10.0);
|
||||
|
||||
irom->setMax_size(irom_max*10.0);
|
||||
|
||||
|
||||
bool is_Image_component_sizes=false;
|
||||
bool is_Totals=false;
|
||||
|
||||
// info_list.clear();
|
||||
|
||||
for(auto ram:ram_list)
|
||||
{
|
||||
delete ram;
|
||||
}
|
||||
ram_list.clear();
|
||||
|
||||
for(auto flash:flash_list)
|
||||
{
|
||||
delete flash;
|
||||
}
|
||||
|
||||
flash_list.clear();
|
||||
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
qDebug()<<"open fail"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
while (!file.atEnd())
|
||||
{
|
||||
QByteArray line = file.readLine();
|
||||
QString str(line);
|
||||
|
||||
if(str.contains("Program Size"))
|
||||
{
|
||||
|
||||
// qDebug() << str;
|
||||
// parse_excution_region_info(str);
|
||||
|
||||
QStringList str_list= str.split(" ");
|
||||
|
||||
for(int i=0;i<str_list.length();i++)
|
||||
{
|
||||
// qDebug() << str_list[i];
|
||||
if(str_list[i].contains("xdata"))
|
||||
{
|
||||
xram->setUsed_size((str_list[i].split("=")[1].toFloat())*10.0);
|
||||
xram->setRemain_size(xram->getMax_size()-xram->getUsed_size());
|
||||
}else if(str_list[i].contains("XDATA"))
|
||||
{
|
||||
xram->setUsed_size((str_list[i].split("=")[1].toFloat())*10.0);
|
||||
xram->setRemain_size(xram->getMax_size()-xram->getUsed_size());
|
||||
}else if(str_list[i].contains("data"))
|
||||
{
|
||||
|
||||
|
||||
iram->setUsed_size((str_list[i].split("=")[1].toFloat())*10.0);
|
||||
iram->setRemain_size(iram->getMax_size()-iram->getUsed_size());
|
||||
}else if(str_list[i].contains("DATA"))
|
||||
{
|
||||
iram->setUsed_size((str_list[i].split("=")[1].toFloat())*10.0);
|
||||
iram->setRemain_size(iram->getMax_size()-iram->getUsed_size());
|
||||
}else if(str_list[i].contains("code"))
|
||||
{
|
||||
irom->setUsed_size((str_list[i].split("=")[1].toFloat())*10.0);
|
||||
irom->setRemain_size(irom->getMax_size()-irom->getUsed_size());
|
||||
}else if(str_list[i].contains("code"))
|
||||
{
|
||||
irom->setUsed_size((str_list[i].split("=")[1].toFloat())*10.0);
|
||||
irom->setRemain_size(irom->getMax_size()-irom->getUsed_size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// else if(str.contains("Image component sizes"))
|
||||
// {
|
||||
// is_Image_component_sizes=true;
|
||||
//// qDebug()<<str;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
file.close();
|
||||
|
||||
|
||||
ram_list.append(iram);
|
||||
if(xram->getMax_size()>0)
|
||||
ram_list.append(xram);
|
||||
flash_list.append(irom);
|
||||
|
||||
qDebug()<<"ram:";
|
||||
for(auto ram:ram_list)
|
||||
{
|
||||
ram->print_bar_8051();
|
||||
}
|
||||
qDebug()<<"flash:";
|
||||
for(auto flash:flash_list)
|
||||
{
|
||||
flash->print_bar_8051();
|
||||
}
|
||||
|
||||
|
||||
}
|
32
parse_m51_from_keil.h
Normal file
32
parse_m51_from_keil.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef PARSE_M51_FROM_KEIL_H
|
||||
#define PARSE_M51_FR0M_KEIL_H
|
||||
|
||||
#include <QString>
|
||||
#include "use_percentage_bar.h"
|
||||
#include <QList>
|
||||
|
||||
class parse_m51_from_keil
|
||||
{
|
||||
public:
|
||||
parse_m51_from_keil(QString path,uint64_t iram_max_size,uint64_t xram_max_size,
|
||||
uint64_t irom_max_size);
|
||||
|
||||
uint64_t all_ram_size=0;
|
||||
uint64_t all_flash_size=0;
|
||||
|
||||
uint64_t iram_max;
|
||||
uint64_t xram_max;
|
||||
uint64_t irom_max;
|
||||
use_percentage_bar* iram;
|
||||
use_percentage_bar* xram;
|
||||
use_percentage_bar* irom;
|
||||
QList<use_percentage_bar*>ram_list;
|
||||
QList<use_percentage_bar*>flash_list;
|
||||
|
||||
|
||||
bool to_parse_m51_from_keil(QString path);
|
||||
QString find_m51_path(const QString& dir_path);
|
||||
bool parse_m51_file(QString path);
|
||||
};
|
||||
|
||||
#endif // PARSE_M51_FROM_KEIL_H
|
330
parse_map_from_keil.cpp
Normal file
330
parse_map_from_keil.cpp
Normal file
@ -0,0 +1,330 @@
|
||||
#include "parse_map_from_keil.h"
|
||||
#include <QFile>
|
||||
#include <QDomDocument>
|
||||
#include <Qtxml>
|
||||
#include <QDebug>
|
||||
#include <qxmlstream.h>
|
||||
#include "find_path.h"
|
||||
#include <QRegExp>
|
||||
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
extern MainWindow* main_window;
|
||||
|
||||
QString parse_map_from_keil::find_map_path(const QString& dir_path)
|
||||
{
|
||||
|
||||
|
||||
QString map_file_path;
|
||||
map_file_path=find_path::find_file_path(dir_path,".map");
|
||||
if(map_file_path.length()<3)
|
||||
map_file_path=find_path::find_file_path(dir_path,".MAP");
|
||||
|
||||
return map_file_path;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool parse_map_from_keil::parse_excution_region_info(QString info_string)
|
||||
{
|
||||
|
||||
// storage_type_t storage=ram;
|
||||
use_percentage_bar* storage=new use_percentage_bar(nullptr);
|
||||
storage->setStorage(flash);
|
||||
for(auto keyword:ram_keyword)
|
||||
{
|
||||
if(info_string.contains(keyword))
|
||||
{
|
||||
// qDebug()<<info_string;
|
||||
storage->setStorage(ram);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
info_string.remove("Execution Region", Qt::CaseInsensitive);//去除"Execution Region"
|
||||
info_string.remove(QChar(' '), Qt::CaseInsensitive);//去除" "
|
||||
|
||||
storage->setName(info_string.split("(")[0]);
|
||||
QStringList info_list =info_string.split("(")[1].split(",");
|
||||
|
||||
|
||||
|
||||
for(auto info :info_list)
|
||||
{
|
||||
QStringList info_value;
|
||||
info.remove(QChar(','), Qt::CaseInsensitive);//去除","
|
||||
info.remove(QChar(' '), Qt::CaseInsensitive);//去除")"
|
||||
|
||||
|
||||
if(info.contains("Exec")||info.contains("Base"))
|
||||
{
|
||||
info_value =info.split(":");
|
||||
info_value[1].remove(QChar('x'), Qt::CaseInsensitive);//去除"x"
|
||||
storage->setBase_addr(info_value[1].toUInt(nullptr,16));
|
||||
// qDebug()<<info_value[1];
|
||||
|
||||
if(storage->getBase_addr()>iram_base&&storage->getBase_addr()<iram_base+iram_max_size)
|
||||
storage->setStorage(ram);
|
||||
else if(storage->getBase_addr()>irom_base&&storage->getBase_addr()<irom_base+irom_max_size)
|
||||
storage->setStorage(flash);
|
||||
|
||||
}else if(info.contains("Size"))
|
||||
{
|
||||
|
||||
info_value =info.split(":");
|
||||
info_value[1].remove(QChar('x'), Qt::CaseInsensitive);//去除"x"
|
||||
|
||||
storage->setUsed_size(info_value[1].toUInt(nullptr,16));
|
||||
// qDebug()<<info_value[1];
|
||||
|
||||
|
||||
|
||||
}else if(info.contains("Max"))
|
||||
{
|
||||
|
||||
info_value =info.split(":");
|
||||
info_value[1].remove(QChar('x'), Qt::CaseInsensitive);//去除"x"
|
||||
storage->setMax_size(info_value[1].toUInt(nullptr,16));
|
||||
// qDebug()<<info_value[1];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(storage->getStorage()==ram)
|
||||
ram_list.append(storage);
|
||||
else
|
||||
flash_list.append(storage);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool parse_map_from_keil::parse_map_file(QString path){
|
||||
|
||||
QFile file(path);
|
||||
|
||||
bool is_Image_component_sizes=false;
|
||||
bool is_Totals=false;
|
||||
|
||||
|
||||
for(auto info:info_list)
|
||||
{
|
||||
delete info;
|
||||
}
|
||||
info_list.clear();
|
||||
|
||||
for(auto ram:ram_list)
|
||||
{
|
||||
delete ram;
|
||||
}
|
||||
ram_list.clear();
|
||||
|
||||
|
||||
for(auto flash:flash_list)
|
||||
{
|
||||
delete flash;
|
||||
}
|
||||
flash_list.clear();
|
||||
|
||||
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
qDebug()<<"open fail"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!file.atEnd())
|
||||
{
|
||||
QByteArray line = file.readLine();
|
||||
QString str(line);
|
||||
|
||||
if(str.contains("Execution Region"))
|
||||
{
|
||||
|
||||
// qDebug() << str;
|
||||
parse_excution_region_info(str);
|
||||
}else if(str.contains("Image component sizes"))
|
||||
{
|
||||
is_Image_component_sizes=true;
|
||||
// qDebug()<<str;
|
||||
}
|
||||
|
||||
if(is_Image_component_sizes)
|
||||
{
|
||||
if(str.contains("----"))
|
||||
{
|
||||
if(is_Totals)
|
||||
{
|
||||
is_Totals=false;
|
||||
}else
|
||||
{
|
||||
is_Totals=true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if(str.contains("=====")){
|
||||
is_Image_component_sizes=false;
|
||||
}else if(str==""||str.length()<10)
|
||||
{
|
||||
|
||||
}
|
||||
else {
|
||||
// 使用正则表达式提取数字和单词
|
||||
QRegExp rx("(\\d+|\\w+)");
|
||||
|
||||
// 将多个空格替换为逗号
|
||||
QString csv_row = str.trimmed().replace(QRegExp("\\s+"), ",");
|
||||
csv_row+="\n";
|
||||
// 输出修改后的数据
|
||||
// qDebug() << csv_row;
|
||||
|
||||
QStringList item_data= csv_row.split(",");
|
||||
|
||||
|
||||
if(item_data.length()<=8)
|
||||
{
|
||||
bool is_number=false;
|
||||
if(is_Totals)
|
||||
{
|
||||
if(item_data.length()>7&&item_data[7].contains("Totals"))
|
||||
{
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
item_data[1].toUInt(&is_number);
|
||||
if(is_number)
|
||||
{
|
||||
|
||||
image_item_t* item=new image_item_t();
|
||||
item->Code=QString::number(item_data[0].toInt());//item_data[1].toUInt()(inc.data是包含在code内的)
|
||||
item->RO_Data=item_data[2];
|
||||
item->RW_Data=item_data[3];
|
||||
item->ZI_Data=item_data[4];
|
||||
item->Debug=item_data[5];
|
||||
item->Object_Name=item_data[6];
|
||||
|
||||
if(item->Object_Name.contains(".l"))
|
||||
continue;
|
||||
else if (item->Object_Name.contains("(")) {
|
||||
item->Object_Name=item->Object_Name=item_data[6]+item_data[7];
|
||||
|
||||
}
|
||||
|
||||
info_list.append(item);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qDebug()<<"ram:";
|
||||
for(auto ram:ram_list)
|
||||
{
|
||||
ram->print_bar();
|
||||
}
|
||||
qDebug()<<"flash:";
|
||||
for(auto flash:flash_list)
|
||||
{
|
||||
flash->print_bar();
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
|
||||
}
|
||||
|
||||
QString parse_map_from_keil::getMap_path() const
|
||||
{
|
||||
return map_path;
|
||||
}
|
||||
|
||||
void parse_map_from_keil::setMap_path(const QString &value)
|
||||
{
|
||||
map_path = value;
|
||||
}
|
||||
|
||||
QList<image_item_t*> parse_map_from_keil::getInfo_list() const
|
||||
{
|
||||
return info_list;
|
||||
}
|
||||
|
||||
void parse_map_from_keil::setInfo_list(const QList<image_item_t*> &value)
|
||||
{
|
||||
info_list = value;
|
||||
}
|
||||
|
||||
uint64_t parse_map_from_keil::getAll_ram_size() const
|
||||
{
|
||||
return all_ram_size;
|
||||
}
|
||||
|
||||
uint64_t parse_map_from_keil::getAll_flash_size() const
|
||||
{
|
||||
return all_flash_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool parse_map_from_keil::to_parse_map_from_keil(QString path)
|
||||
{
|
||||
|
||||
map_path=path;
|
||||
QString file_path;
|
||||
|
||||
|
||||
if(path.contains(".map")||path.contains(".MAP"))
|
||||
{
|
||||
parse_map_file(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
file_path=find_map_path(path);
|
||||
qDebug()<<file_path;
|
||||
|
||||
if(file_path.length()>3)
|
||||
{
|
||||
parse_map_file(file_path);
|
||||
return true;
|
||||
}else
|
||||
{
|
||||
qDebug()<<"路径错误";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
parse_map_from_keil::parse_map_from_keil(QString path, uint64_t to_iram_base,
|
||||
uint64_t to_iram_max_size,
|
||||
uint64_t to_irom_base,
|
||||
uint64_t to_irom_max_size)
|
||||
{
|
||||
|
||||
|
||||
iram_base=to_iram_base;
|
||||
iram_max_size=to_iram_base;
|
||||
irom_base=to_irom_base;
|
||||
irom_max_size= to_irom_max_size;
|
||||
|
||||
//to_parse_map_from_keil(path);
|
||||
|
||||
}
|
74
parse_map_from_keil.h
Normal file
74
parse_map_from_keil.h
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef PARSE_MAP_FROM_KEIL_H
|
||||
#define PARSE_MAP_FROM_KEIL_H
|
||||
|
||||
#include <QString>
|
||||
#include "use_percentage_bar.h"
|
||||
#include <QList>
|
||||
|
||||
|
||||
typedef struct {QString fn_name;QString file_name; uint64_t size;}map_item;
|
||||
|
||||
|
||||
typedef struct image_item {
|
||||
|
||||
QString Code;
|
||||
QString RO_Data;
|
||||
QString RW_Data;
|
||||
QString ZI_Data;
|
||||
QString Debug;
|
||||
QString Object_Name;
|
||||
|
||||
}image_item_t;
|
||||
|
||||
class parse_map_from_keil
|
||||
{
|
||||
|
||||
public:
|
||||
bool to_parse_map_from_keil(QString path);
|
||||
parse_map_from_keil(QString path,
|
||||
uint64_t to_iram_base,
|
||||
uint64_t to_iram_max_size,
|
||||
uint64_t to_irom_base,
|
||||
uint64_t to_irom_max_size
|
||||
);
|
||||
QString find_map_path(const QString& dir_path);
|
||||
bool parse_excution_region_info(QString info_string);
|
||||
bool parse_map_file(QString path);
|
||||
|
||||
|
||||
QList<use_percentage_bar*>ram_list;
|
||||
QList<use_percentage_bar*>flash_list;
|
||||
|
||||
|
||||
QString getMap_path() const;
|
||||
void setMap_path(const QString &value);
|
||||
|
||||
QList<image_item_t*> getInfo_list() const;
|
||||
void setInfo_list(const QList<image_item_t*> &value);
|
||||
|
||||
uint64_t getAll_ram_size() const;
|
||||
|
||||
uint64_t getAll_flash_size() const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
uint64_t iram_base;
|
||||
uint64_t iram_max_size;
|
||||
|
||||
uint64_t irom_base;
|
||||
uint64_t irom_max_size;
|
||||
|
||||
|
||||
|
||||
uint64_t all_ram_size=0;
|
||||
uint64_t all_flash_size=0;
|
||||
//,"HEAP","STACK","heap","stack"
|
||||
QList<QString> ram_keyword={"ER$$","RW_","ER_RW","ER_ZI"};
|
||||
QList<QString> flash_keyword={"RO","FLASH","flash","ro","text","TEXT"};
|
||||
|
||||
QString map_path;
|
||||
QList<image_item_t*> info_list;
|
||||
};
|
||||
|
||||
#endif // PARSE_MAP_FROM_KEIL_H
|
301
use_percentage_bar.cpp
Normal file
301
use_percentage_bar.cpp
Normal file
@ -0,0 +1,301 @@
|
||||
#include "use_percentage_bar.h"
|
||||
#include "ui_use_percentage_bar.h"
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <flatui.h>
|
||||
|
||||
use_percentage_bar::use_percentage_bar(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::use_percentage_bar)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
FlatUI::setProgressQss(ui->used_bar, 20,12,16, "#747976", "#1ABC9C");
|
||||
|
||||
}
|
||||
void use_percentage_bar::set_bar_style(QProgressBar *bar,float per)
|
||||
{
|
||||
if( per/1.0>0.85)
|
||||
{
|
||||
FlatUI::setProgressQss(bar, 20,12,16, "#747976", "#E74C3C");
|
||||
|
||||
}else if( per>0.75)
|
||||
{
|
||||
FlatUI::setProgressQss(bar, 20,12,16, "#747976", "#F9D927");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FlatUI::setProgressQss(bar, 20,12,16, "#747976", "#1ABC9C");
|
||||
}
|
||||
|
||||
}
|
||||
use_percentage_bar::~use_percentage_bar()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
void use_percentage_bar::print_bar_8051(void)
|
||||
{
|
||||
|
||||
if(max_size==0)
|
||||
{
|
||||
qDebug()<<"erro:max=0";
|
||||
return;
|
||||
}
|
||||
uint8_t i;
|
||||
QString bar_str;
|
||||
qDebug()<<name<<":0";//<<QString().sprintf("%#x",base_addr);
|
||||
|
||||
if(max_size/10.0<=1024)
|
||||
{
|
||||
bar_str+=QString().sprintf("%6.2f B %5s:|", max_size/10.0 , name.toStdString().data());
|
||||
}
|
||||
else
|
||||
{
|
||||
bar_str+=QString().sprintf("%6.2f KB %5s:|", max_size/10.0/1024.0 , name.toStdString().data());
|
||||
}
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
if (i < (uint8_t)((used_size / 1.0) / (max_size / 1.0) * 20))
|
||||
{
|
||||
|
||||
bar_str+=QString().sprintf("■");
|
||||
}
|
||||
else
|
||||
{
|
||||
bar_str+=QString().sprintf("_");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(max_size/10.0<=1024)
|
||||
{
|
||||
bar_str+=QString().sprintf("|%6.2f %% (%8.2f B / %8.2f B)", (used_size/10.0 / 1.0) / (max_size/10.0 / 1.0) * 100, used_size/10.0 , max_size/10.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
bar_str+=QString().sprintf("|%6.2f %% (%8.2f B / %8.2f KB)", (used_size/10.0 / 1.0) / (max_size/10.0 / 1.0) * 100, used_size/10.0 , max_size/10.0 / 1024.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bar_str+=QString().sprintf(" [%u B]", max_size/10.0 - used_size/10.0);
|
||||
qDebug()<< bar_str;
|
||||
|
||||
}
|
||||
void use_percentage_bar::print_bar(void)
|
||||
{
|
||||
|
||||
if(max_size==0)
|
||||
{
|
||||
qDebug()<<"erro:max=0";
|
||||
return;
|
||||
}
|
||||
uint8_t i;
|
||||
QString bar_str;
|
||||
qDebug()<<name<<":"<<QString().sprintf("%#x",base_addr);
|
||||
bar_str+=QString().sprintf("%6.2f KB %5s:|", max_size / 1024.0f, storage==ram?"ram":"flash");
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
if (i < (uint8_t)((used_size / 1.0) / (max_size / 1.0) * 20))
|
||||
{
|
||||
|
||||
bar_str+=QString().sprintf("■");
|
||||
}
|
||||
else
|
||||
{
|
||||
bar_str+=QString().sprintf("_");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(max_size<=1024*1024)
|
||||
{
|
||||
bar_str+=QString().sprintf("|%6.2f %% (%8.2f KB / %8.2f KB)", (used_size / 1.0) / (max_size / 1.0) * 100, used_size / 1024.0f, max_size / 1024.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
bar_str+=QString().sprintf("|%6.2f %% (%8.4f MB / %8.4f MB)", (used_size / 1.0) / (max_size / 1.0) * 100, used_size / 1024.0f/1024.0f, max_size / 1024.0f/1024.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bar_str+=QString().sprintf(" [%u B]", max_size - used_size);
|
||||
qDebug()<< bar_str;
|
||||
|
||||
}
|
||||
|
||||
QString use_percentage_bar::getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void use_percentage_bar::setName(const QString &value)
|
||||
{
|
||||
name = value;
|
||||
|
||||
|
||||
ui->name->setTitle(name);
|
||||
}
|
||||
|
||||
storage_type_t use_percentage_bar::getStorage() const
|
||||
{
|
||||
return storage;
|
||||
}
|
||||
|
||||
void use_percentage_bar::setStorage(const storage_type_t &value)
|
||||
{
|
||||
storage = value;
|
||||
}
|
||||
|
||||
uint64_t use_percentage_bar::getBase_addr() const
|
||||
{
|
||||
return base_addr;
|
||||
}
|
||||
|
||||
void use_percentage_bar::setBase_addr(const uint64_t &value)
|
||||
{
|
||||
base_addr = value;
|
||||
ui->addr->setText(QString().sprintf("地址:%#x", base_addr));
|
||||
}
|
||||
|
||||
uint64_t use_percentage_bar::getLoad_addr() const
|
||||
{
|
||||
return load_addr;
|
||||
}
|
||||
|
||||
void use_percentage_bar::setLoad_addr(const uint64_t &value)
|
||||
{
|
||||
load_addr = value;
|
||||
}
|
||||
|
||||
uint64_t use_percentage_bar::getLoad_max_size() const
|
||||
{
|
||||
return load_max_size;
|
||||
}
|
||||
|
||||
void use_percentage_bar::setLoad_max_size(const uint64_t &value)
|
||||
{
|
||||
load_max_size = value;
|
||||
|
||||
}
|
||||
|
||||
uint64_t use_percentage_bar::getUsed_size() const
|
||||
{
|
||||
return used_size;
|
||||
}
|
||||
|
||||
void use_percentage_bar::setUsed_size(const uint64_t &value)
|
||||
{
|
||||
used_size = value;
|
||||
if(max_size!=0)
|
||||
{
|
||||
ui->used_bar->setRange(0,max_size);
|
||||
ui->used_bar->setValue(used_size);
|
||||
|
||||
if(storage==mc8051)
|
||||
{
|
||||
if(max_size/10.0<=1024)
|
||||
{
|
||||
ui->used->setText(QString().sprintf("占用:%.2f B / (%.2f B)",used_size/10.0,max_size/10.0));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->used->setText(QString().sprintf("占用:%.2f B / (%.2f KB)",used_size/10.0,max_size/10.0/1024.0));
|
||||
|
||||
}
|
||||
setRemain_size(max_size-used_size);
|
||||
}else
|
||||
{
|
||||
if(max_size<=1024*1024)
|
||||
{
|
||||
ui->used->setText(QString().sprintf("占用:%.2f KB / (%.2f KB)",used_size/1024.0,max_size/1024.0));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->used->setText(QString().sprintf("占用:%.4f MB / (%.4f MB)",used_size/1024.0/1024.0,max_size/1024.0/1024.0));
|
||||
|
||||
}
|
||||
setRemain_size(max_size-used_size);
|
||||
}
|
||||
set_bar_style(ui->used_bar,used_size/1.0/max_size/1.0);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t use_percentage_bar::getMax_size() const
|
||||
{
|
||||
return max_size;
|
||||
}
|
||||
|
||||
void use_percentage_bar::setMax_size(const uint64_t &value)
|
||||
{
|
||||
max_size = value;
|
||||
|
||||
if(max_size!=0)
|
||||
{
|
||||
|
||||
ui->used_bar->setRange(0,max_size);
|
||||
ui->used_bar->setValue(used_size);
|
||||
|
||||
|
||||
if(storage==mc8051)
|
||||
{
|
||||
|
||||
|
||||
if(max_size/10.0<=1024)
|
||||
{
|
||||
ui->used->setText(QString().sprintf("占用:%.2f B / (%.2f B)",used_size/10.0,max_size/10.0));
|
||||
|
||||
}else
|
||||
{
|
||||
ui->used->setText(QString().sprintf("占用:%.2f B / (%.2f KB)",used_size/10.0,max_size/10.0/1024.0));
|
||||
|
||||
}
|
||||
setRemain_size(max_size-used_size);
|
||||
}else
|
||||
{
|
||||
if(max_size<=1024*1024)
|
||||
{
|
||||
ui->used->setText(QString().sprintf("占用:%.2f KB / (%.2f KB)",used_size/1024.0,max_size/1024.0));
|
||||
|
||||
}else
|
||||
{
|
||||
ui->used->setText(QString().sprintf("占用:%.4f MB / (%.4f MB)",used_size/1024.0/1024.0,max_size/1024.0/1024.0));
|
||||
|
||||
}
|
||||
setRemain_size(max_size-used_size);
|
||||
}
|
||||
set_bar_style(ui->used_bar,used_size/1.0/max_size/1.0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint64_t use_percentage_bar::getRemain_size() const
|
||||
{
|
||||
return remain_size;
|
||||
}
|
||||
|
||||
void use_percentage_bar::setRemain_size(const uint64_t &value)
|
||||
{
|
||||
remain_size = value;
|
||||
if(storage==mc8051)
|
||||
{
|
||||
ui->remain->setText(QString().sprintf("剩余:%.2f B",remain_size/10.0));
|
||||
}else
|
||||
{
|
||||
ui->remain->setText(QString().sprintf("剩余:%llu B",remain_size));
|
||||
}
|
||||
}
|
||||
|
61
use_percentage_bar.h
Normal file
61
use_percentage_bar.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef USE_PERCENTAGE_BAR_H
|
||||
#define USE_PERCENTAGE_BAR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QProgressBar>
|
||||
namespace Ui {
|
||||
class use_percentage_bar;
|
||||
}
|
||||
typedef enum storage_type {ram,flash,mc8051 }storage_type_t;
|
||||
|
||||
class use_percentage_bar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit use_percentage_bar(QWidget *parent = nullptr);
|
||||
~use_percentage_bar();
|
||||
|
||||
|
||||
void print_bar(void);
|
||||
void print_bar_8051(void);
|
||||
|
||||
QString getName() const;
|
||||
void setName(const QString &value);
|
||||
|
||||
storage_type_t getStorage() const;
|
||||
void setStorage(const storage_type_t &value);
|
||||
|
||||
uint64_t getBase_addr() const;
|
||||
void setBase_addr(const uint64_t &value);
|
||||
|
||||
uint64_t getLoad_addr() const;
|
||||
void setLoad_addr(const uint64_t &value);
|
||||
|
||||
uint64_t getLoad_max_size() const;
|
||||
void setLoad_max_size(const uint64_t &value);
|
||||
|
||||
uint64_t getUsed_size() const;
|
||||
void setUsed_size(const uint64_t &value);
|
||||
|
||||
uint64_t getMax_size() const;
|
||||
void setMax_size(const uint64_t &value);
|
||||
|
||||
uint64_t getRemain_size() const;
|
||||
void setRemain_size(const uint64_t &value);
|
||||
|
||||
private:
|
||||
Ui::use_percentage_bar *ui;
|
||||
|
||||
QString name;
|
||||
storage_type_t storage;
|
||||
uint64_t base_addr;
|
||||
uint64_t load_addr;
|
||||
uint64_t load_max_size;
|
||||
uint64_t used_size;
|
||||
uint64_t max_size;
|
||||
uint64_t remain_size;
|
||||
void set_bar_style(QProgressBar *bar,float per);
|
||||
};
|
||||
|
||||
#endif // USE_PERCENTAGE_BAR_H
|
61
use_percentage_bar.ui
Normal file
61
use_percentage_bar.ui
Normal file
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>use_percentage_bar</class>
|
||||
<widget class="QWidget" name="use_percentage_bar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="name">
|
||||
<property name="title">
|
||||
<string>RAM/Flash</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="addr">
|
||||
<property name="text">
|
||||
<string>地址:0x0000000</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="used_bar">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="used">
|
||||
<property name="text">
|
||||
<string> 占用:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="remain">
|
||||
<property name="text">
|
||||
<string> 还剩:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
x
Reference in New Issue
Block a user