首次提交
This commit is contained in:
17
README.md
Normal file
17
README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
#### 项目介绍
|
||||
Qt编写的一些开源的demo,包括串口调试助手、网络调试助手、自定义控件、其他小demo等,会一直持续更新完善,代码随意传播使用,拒绝打赏和捐赠,欢迎各位留言评论!
|
||||
|
||||
#### 目录说明
|
||||
| 编号 | 文件夹 | 描述 |
|
||||
| ------ | ------ | ------ |
|
||||
| 1 | lightbutton | 高亮按钮控件 |
|
||||
| 2 | movewidget | 通用控件移动类 |
|
||||
| 3 | flatui | 模仿flatui类 |
|
||||
| 4 | countcode | 代码统计组件 |
|
||||
| 5 | gifwidget | 屏幕录制控件 |
|
||||
| 6 | comtool | 串口调试助手 |
|
||||
| 7 | nettool | 网络调试助手 |
|
||||
| 8 | devicesizetable | 硬盘容量控件 |
|
||||
| 9 | styledemo | 高仿PS黑色+扁平白色+淡蓝色风格主题 |
|
||||
| 10 | navbutton | 导航按钮控件 |
|
||||
| 11 | video_splite | 视频监控画面分割demo |
|
||||
7
comtool/api/api.pri
Normal file
7
comtool/api/api.pri
Normal file
@@ -0,0 +1,7 @@
|
||||
HEADERS += \
|
||||
$$PWD/app.h \
|
||||
$$PWD/quiwidget.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/app.cpp \
|
||||
$$PWD/quiwidget.cpp
|
||||
201
comtool/api/app.cpp
Normal file
201
comtool/api/app.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
#include "app.h"
|
||||
#include "quiwidget.h"
|
||||
|
||||
QString App::ConfigFile = "config.ini";
|
||||
QString App::SendFileName = "send.txt";
|
||||
QString App::DeviceFileName = "device.txt";
|
||||
|
||||
QString App::PortName = "COM1";
|
||||
int App::BaudRate = 9600;
|
||||
int App::DataBit = 8;
|
||||
QString App::Parity = "无";
|
||||
double App::StopBit = 1;
|
||||
|
||||
bool App::HexSend = false;
|
||||
bool App::HexReceive = false;
|
||||
bool App::Debug = false;
|
||||
bool App::AutoClear = false;
|
||||
|
||||
bool App::AutoSend = false;
|
||||
int App::SendInterval = 1000;
|
||||
bool App::AutoSave = false;
|
||||
int App::SaveInterval = 5000;
|
||||
|
||||
QString App::Mode = "Tcp_Client";
|
||||
QString App::ServerIP = "127.0.0.1";
|
||||
int App::ServerPort = 6000;
|
||||
int App::ListenPort = 6000;
|
||||
int App::SleepTime = 100;
|
||||
bool App::AutoConnect = false;
|
||||
|
||||
void App::readConfig()
|
||||
{
|
||||
if (!checkConfig()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QSettings set(App::ConfigFile, QSettings::IniFormat);
|
||||
|
||||
set.beginGroup("ComConfig");
|
||||
App::PortName = set.value("PortName").toString();
|
||||
App::BaudRate = set.value("BaudRate").toInt();
|
||||
App::DataBit = set.value("DataBit").toInt();
|
||||
App::Parity = set.value("Parity").toString();
|
||||
App::StopBit = set.value("StopBit").toInt();
|
||||
|
||||
App::HexSend = set.value("HexSend").toBool();
|
||||
App::HexReceive = set.value("HexReceive").toBool();
|
||||
App::Debug = set.value("Debug").toBool();
|
||||
App::AutoClear = set.value("AutoClear").toBool();
|
||||
|
||||
App::AutoSend = set.value("AutoSend").toBool();
|
||||
App::SendInterval = set.value("SendInterval").toInt();
|
||||
App::AutoSave = set.value("AutoSave").toBool();
|
||||
App::SaveInterval = set.value("SaveInterval").toInt();
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("NetConfig");
|
||||
App::Mode = set.value("Mode").toString();
|
||||
App::ServerIP = set.value("ServerIP").toString();
|
||||
App::ServerPort = set.value("ServerPort").toInt();
|
||||
App::ListenPort = set.value("ListenPort").toInt();
|
||||
App::SleepTime = set.value("SleepTime").toInt();
|
||||
App::AutoConnect = set.value("AutoConnect").toBool();
|
||||
set.endGroup();
|
||||
}
|
||||
|
||||
void App::writeConfig()
|
||||
{
|
||||
QSettings set(App::ConfigFile, QSettings::IniFormat);
|
||||
|
||||
set.beginGroup("ComConfig");
|
||||
set.setValue("PortName", App::PortName);
|
||||
set.setValue("BaudRate", App::BaudRate);
|
||||
set.setValue("DataBit", App::DataBit);
|
||||
set.setValue("Parity", App::Parity);
|
||||
set.setValue("StopBit", App::StopBit);
|
||||
|
||||
set.setValue("HexSend", App::HexSend);
|
||||
set.setValue("HexReceive", App::HexReceive);
|
||||
set.setValue("Debug", App::Debug);
|
||||
set.setValue("AutoClear", App::AutoClear);
|
||||
|
||||
set.setValue("AutoSend", App::AutoSend);
|
||||
set.setValue("SendInterval", App::SendInterval);
|
||||
set.setValue("AutoSave", App::AutoSave);
|
||||
set.setValue("SaveInterval", App::SaveInterval);
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("NetConfig");
|
||||
set.setValue("Mode", App::Mode);
|
||||
set.setValue("ServerIP", App::ServerIP);
|
||||
set.setValue("ServerPort", App::ServerPort);
|
||||
set.setValue("ListenPort", App::ListenPort);
|
||||
set.setValue("SleepTime", App::SleepTime);
|
||||
set.setValue("AutoConnect", App::AutoConnect);
|
||||
set.endGroup();
|
||||
}
|
||||
|
||||
void App::newConfig()
|
||||
{
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
App::Parity = App::Parity.toLatin1();
|
||||
#endif
|
||||
writeConfig();
|
||||
}
|
||||
|
||||
bool App::checkConfig()
|
||||
{
|
||||
//如果配置文件大小为0,则以初始值继续运行,并生成配置文件
|
||||
QFile file(App::ConfigFile);
|
||||
if (file.size() == 0) {
|
||||
newConfig();
|
||||
return false;
|
||||
}
|
||||
|
||||
//如果配置文件不完整,则以初始值继续运行,并生成配置文件
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
bool ok = true;
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
line = line.replace("\r", "");
|
||||
line = line.replace("\n", "");
|
||||
QStringList list = line.split("=");
|
||||
|
||||
if (list.count() == 2) {
|
||||
if (list.at(1) == "") {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
newConfig();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
newConfig();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList App::Intervals = QStringList();
|
||||
QStringList App::Datas = QStringList();
|
||||
QStringList App::Keys = QStringList();
|
||||
QStringList App::Values = QStringList();
|
||||
|
||||
void App::readSendData()
|
||||
{
|
||||
//读取发送数据列表
|
||||
App::Datas.clear();
|
||||
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(App::SendFileName);
|
||||
QFile file(fileName);
|
||||
if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) {
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
line = line.trimmed();
|
||||
line = line.replace("\r", "");
|
||||
line = line.replace("\n", "");
|
||||
if (!line.isEmpty()) {
|
||||
App::Datas.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void App::readDeviceData()
|
||||
{
|
||||
//读取转发数据列表
|
||||
App::Keys.clear();
|
||||
App::Values.clear();
|
||||
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(App::DeviceFileName);
|
||||
QFile file(fileName);
|
||||
if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) {
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
line = line.trimmed();
|
||||
line = line.replace("\r", "");
|
||||
line = line.replace("\n", "");
|
||||
if (!line.isEmpty()) {
|
||||
QStringList list = line.split(";");
|
||||
QString key = list.at(0);
|
||||
QString value;
|
||||
for (int i = 1; i < list.count(); i++) {
|
||||
value += QString("%1;").arg(list.at(i));
|
||||
}
|
||||
|
||||
//去掉末尾分号
|
||||
value = value.mid(0, value.length() - 1);
|
||||
App::Keys.append(key);
|
||||
App::Values.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
51
comtool/api/app.h
Normal file
51
comtool/api/app.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef APP_H
|
||||
#define APP_H
|
||||
|
||||
#include "head.h"
|
||||
|
||||
class App
|
||||
{
|
||||
public:
|
||||
static QString ConfigFile; //配置文件路径
|
||||
static QString SendFileName; //发送配置文件名
|
||||
static QString DeviceFileName; //模拟设备数据文件名
|
||||
|
||||
static QString PortName; //串口号
|
||||
static int BaudRate; //波特率
|
||||
static int DataBit; //数据位
|
||||
static QString Parity; //校验位
|
||||
static double StopBit; //停止位
|
||||
|
||||
static bool HexSend; //16进制发送
|
||||
static bool HexReceive; //16进制接收
|
||||
static bool Debug; //模拟设备
|
||||
static bool AutoClear; //自动清空
|
||||
|
||||
static bool AutoSend; //自动发送
|
||||
static int SendInterval; //自动发送间隔
|
||||
static bool AutoSave; //自动保存
|
||||
static int SaveInterval; //自动保存间隔
|
||||
|
||||
static QString Mode; //转换模式
|
||||
static QString ServerIP; //服务器IP
|
||||
static int ServerPort; //服务器端口
|
||||
static int ListenPort; //监听端口
|
||||
static int SleepTime; //延时时间
|
||||
static bool AutoConnect; //自动重连
|
||||
|
||||
//读写配置参数及其他操作
|
||||
static void readConfig(); //读取配置参数
|
||||
static void writeConfig(); //写入配置参数
|
||||
static void newConfig(); //以初始值新建配置文件
|
||||
static bool checkConfig(); //校验配置文件
|
||||
|
||||
static QStringList Intervals;
|
||||
static QStringList Datas;
|
||||
static QStringList Keys;
|
||||
static QStringList Values;
|
||||
static void readSendData();
|
||||
static void readDeviceData();
|
||||
|
||||
};
|
||||
|
||||
#endif // APP_H
|
||||
3688
comtool/api/quiwidget.cpp
Normal file
3688
comtool/api/quiwidget.cpp
Normal file
File diff suppressed because it is too large
Load Diff
871
comtool/api/quiwidget.h
Normal file
871
comtool/api/quiwidget.h
Normal file
@@ -0,0 +1,871 @@
|
||||
#ifndef QUIWIDGET_H
|
||||
#define QUIWIDGET_H
|
||||
|
||||
#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
|
||||
#define TIME qPrintable(QTime::currentTime().toString("HH:mm:ss"))
|
||||
#define QDATE qPrintable(QDate::currentDate().toString("yyyy-MM-dd"))
|
||||
#define QTIME qPrintable(QTime::currentTime().toString("HH-mm-ss"))
|
||||
#define DATETIME qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"))
|
||||
#define STRDATETIME qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss"))
|
||||
#define STRDATETIMEMS qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss-zzz"))
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#define NEWLINE "\r\n"
|
||||
#else
|
||||
#define NEWLINE "\n"
|
||||
#endif
|
||||
|
||||
#ifdef __arm__
|
||||
#define TitleMinSize 40
|
||||
#else
|
||||
#define TitleMinSize 30
|
||||
#endif
|
||||
|
||||
/**
|
||||
* QUI无边框窗体控件 作者:feiyangqingyun(QQ:517216493)
|
||||
* 1:内置 N >= 17 套精美样式,可直接切换,也可自定义样式路径
|
||||
* 2:可设置部件(左上角图标/最小化按钮/最大化按钮/关闭按钮)的图标或者图片及是否可见
|
||||
* 3:可集成设计师插件,直接拖曳使用,所见即所得
|
||||
* 4:如果需要窗体可拖动大小,设置 setSizeGripEnabled(true);
|
||||
* 5:可设置全局样式 setStyle
|
||||
* 6:可弹出消息框,可选阻塞模式和不阻塞,默认不阻塞 showMessageBoxInfo
|
||||
* 7:可弹出错误框,可选阻塞模式和不阻塞,默认不阻塞 showMessageBoxError
|
||||
* 8:可弹出询问框 showMessageBoxError
|
||||
* 9:可弹出右下角信息框 showTipBox
|
||||
* 10:可弹出输入框 showInputBox
|
||||
* 11:可弹出时间范围选择框 showDateSelect
|
||||
* 12:消息框支持设置倒计时关闭
|
||||
* 13:集成图形字体设置方法及根据指定文字获取图片
|
||||
* 14:集成设置窗体居中显示/设置翻译文件/设置编码/设置延时/设置系统时间等静态方法
|
||||
* 15:集成获取应用程序文件名/文件路径 等方法
|
||||
*/
|
||||
|
||||
#include "head.h"
|
||||
|
||||
#ifdef quc
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT QUIWidget : public QDialog
|
||||
#else
|
||||
class QUIWidget : public QDialog
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(Style)
|
||||
Q_PROPERTY(QString title READ getTitle WRITE setTitle)
|
||||
Q_PROPERTY(Qt::Alignment alignment READ getAlignment WRITE setAlignment)
|
||||
Q_PROPERTY(bool minHide READ getMinHide WRITE setMinHide)
|
||||
Q_PROPERTY(bool exitAll READ getExitAll WRITE setExitAll)
|
||||
|
||||
public:
|
||||
//将部分对象作为枚举值暴露给外部
|
||||
enum Widget {
|
||||
Lab_Ico = 0, //左上角图标
|
||||
BtnMenu = 1, //下拉菜单按钮
|
||||
BtnMenu_Min = 2, //最小化按钮
|
||||
BtnMenu_Max = 3, //最大化按钮
|
||||
BtnMenu_Normal = 4, //还原按钮
|
||||
BtnMenu_Close = 5 //关闭按钮
|
||||
};
|
||||
|
||||
//样式枚举
|
||||
enum Style {
|
||||
Style_Silvery = 0, //银色样式
|
||||
Style_Blue = 1, //蓝色样式
|
||||
Style_LightBlue = 2, //淡蓝色样式
|
||||
Style_DarkBlue = 3, //深蓝色样式
|
||||
Style_Gray = 4, //灰色样式
|
||||
Style_LightGray = 5, //浅灰色样式
|
||||
Style_DarkGray = 6, //深灰色样式
|
||||
Style_Black = 7, //黑色样式
|
||||
Style_LightBlack = 8, //浅黑色样式
|
||||
Style_DarkBlack = 9, //深黑色样式
|
||||
Style_PSBlack = 10, //PS黑色样式
|
||||
Style_FlatBlack = 11, //黑色扁平样式
|
||||
Style_FlatWhite = 12, //白色扁平样式
|
||||
Style_FlatBlue = 13, //蓝色扁平样式
|
||||
Style_Purple = 14, //紫色样式
|
||||
Style_BlackBlue = 15, //黑蓝色样式
|
||||
Style_BlackVideo = 16 //视频监控黑色样式
|
||||
};
|
||||
|
||||
public:
|
||||
explicit QUIWidget(QWidget *parent = 0);
|
||||
~QUIWidget();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
QVBoxLayout *verticalLayout1;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout2;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout4;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout;
|
||||
QToolButton *btnMenu;
|
||||
QPushButton *btnMenu_Min;
|
||||
QPushButton *btnMenu_Max;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widget;
|
||||
QVBoxLayout *verticalLayout3;
|
||||
|
||||
private:
|
||||
QString title; //标题
|
||||
Qt::Alignment alignment; //标题文本对齐
|
||||
bool minHide; //最小化隐藏
|
||||
bool exitAll; //退出整个程序
|
||||
QWidget *mainWidget; //主窗体对象
|
||||
|
||||
public:
|
||||
QLabel *getLabIco() const;
|
||||
QLabel *getLabTitle() const;
|
||||
QToolButton *getBtnMenu() const;
|
||||
QPushButton *getBtnMenuMin() const;
|
||||
QPushButton *getBtnMenuMax() const;
|
||||
QPushButton *getBtnMenuMClose() const;
|
||||
|
||||
QString getTitle() const;
|
||||
Qt::Alignment getAlignment() const;
|
||||
bool getMinHide() const;
|
||||
bool getExitAll() const;
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
void changeStyle(); //更换样式
|
||||
|
||||
private slots:
|
||||
void on_btnMenu_Min_clicked();
|
||||
void on_btnMenu_Max_clicked();
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置部件图标
|
||||
void setIcon(QUIWidget::Widget widget, const QChar &str, quint32 size = 12);
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
//设置部件图片
|
||||
void setPixmap(QUIWidget::Widget widget, const QString &file, const QSize &size = QSize(16, 16));
|
||||
//设置部件是否可见
|
||||
void setVisible(QUIWidget::Widget widget, bool visible = true);
|
||||
//设置只有关闭按钮
|
||||
void setOnlyCloseBtn();
|
||||
|
||||
//设置标题栏高度
|
||||
void setTitleHeight(int height);
|
||||
//设置按钮统一宽度
|
||||
void setBtnWidth(int width);
|
||||
|
||||
//设置标题及文本样式
|
||||
void setTitle(const QString &title);
|
||||
void setAlignment(Qt::Alignment alignment);
|
||||
|
||||
//设置最小化隐藏
|
||||
void setMinHide(bool minHide);
|
||||
|
||||
//设置退出时候直接退出整个应用程序
|
||||
void setExitAll(bool exitAll);
|
||||
|
||||
//设置主窗体
|
||||
void setMainWidget(QWidget *mainWidget);
|
||||
|
||||
Q_SIGNALS:
|
||||
void changeStyle(const QString &qssFile);
|
||||
void closing();
|
||||
};
|
||||
|
||||
//弹出信息框类
|
||||
class QUIMessageBox : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUIMessageBox *Instance();
|
||||
explicit QUIMessageBox(QWidget *parent = 0);
|
||||
~QUIMessageBox();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<QUIMessageBox> self;
|
||||
|
||||
QVBoxLayout *verticalLayout1;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout3;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QLabel *labTime;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout4;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout2;
|
||||
QFrame *frame;
|
||||
QVBoxLayout *verticalLayout4;
|
||||
QHBoxLayout *horizontalLayout1;
|
||||
QLabel *labIcoMain;
|
||||
QSpacerItem *horizontalSpacer1;
|
||||
QLabel *labInfo;
|
||||
QHBoxLayout *horizontalLayout2;
|
||||
QSpacerItem *horizontalSpacer2;
|
||||
QPushButton *btnOk;
|
||||
QPushButton *btnCancel;
|
||||
|
||||
private:
|
||||
int closeSec; //总显示时间
|
||||
int currentSec; //当前已显示时间
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
void checkSec(); //校验倒计时
|
||||
|
||||
private slots:
|
||||
void on_btnOk_clicked();
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
void setMessage(const QString &msg, int type, int closeSec = 0);
|
||||
};
|
||||
|
||||
//右下角弹出框类
|
||||
class QUITipBox : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUITipBox *Instance();
|
||||
explicit QUITipBox(QWidget *parent = 0);
|
||||
~QUITipBox();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<QUITipBox> self;
|
||||
|
||||
QVBoxLayout *verticalLayout;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout2;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QLabel *labTime;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout2;
|
||||
QLabel *labInfo;
|
||||
|
||||
QPropertyAnimation *animation;
|
||||
bool fullScreen;
|
||||
|
||||
private:
|
||||
int closeSec; //总显示时间
|
||||
int currentSec; //当前已显示时间
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
void checkSec(); //校验倒计时
|
||||
|
||||
private slots:
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
void setTip(const QString &title, const QString &tip, bool fullScreen = false, bool center = true, int closeSec = 0);
|
||||
void hide();
|
||||
};
|
||||
|
||||
|
||||
//弹出输入框类
|
||||
class QUIInputBox : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUIInputBox *Instance();
|
||||
explicit QUIInputBox(QWidget *parent = 0);
|
||||
~QUIInputBox();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *);
|
||||
void closeEvent(QCloseEvent *);
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<QUIInputBox> self;
|
||||
|
||||
QVBoxLayout *verticalLayout1;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout1;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QLabel *labTime;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout2;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout2;
|
||||
QFrame *frame;
|
||||
QVBoxLayout *verticalLayout3;
|
||||
QLabel *labInfo;
|
||||
QLineEdit *txtValue;
|
||||
QComboBox *cboxValue;
|
||||
QHBoxLayout *lay;
|
||||
QSpacerItem *horizontalSpacer;
|
||||
QPushButton *btnOk;
|
||||
QPushButton *btnCancel;
|
||||
|
||||
private:
|
||||
int closeSec; //总显示时间
|
||||
int currentSec; //当前已显示时间
|
||||
QString value; //当前值
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
void checkSec(); //校验倒计时
|
||||
|
||||
private slots:
|
||||
void on_btnOk_clicked();
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public:
|
||||
QString getValue()const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
void setParameter(const QString &title, int type = 0, int closeSec = 0,
|
||||
QString placeholderText = QString(), bool pwd = false,
|
||||
const QString &defaultValue = QString());
|
||||
|
||||
};
|
||||
|
||||
//弹出日期选择对话框
|
||||
class QUIDateSelect : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUIDateSelect *Instance();
|
||||
explicit QUIDateSelect(QWidget *parent = 0);
|
||||
~QUIDateSelect();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<QUIDateSelect> self;
|
||||
|
||||
QVBoxLayout *verticalLayout;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout1;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout1;
|
||||
QFrame *frame;
|
||||
QGridLayout *gridLayout;
|
||||
QLabel *labStart;
|
||||
QPushButton *btnOk;
|
||||
QLabel *labEnd;
|
||||
QPushButton *btnClose;
|
||||
QDateTimeEdit *dateStart;
|
||||
QDateTimeEdit *dateEnd;
|
||||
|
||||
private:
|
||||
QString startDateTime; //开始时间
|
||||
QString endDateTime; //结束时间
|
||||
QString format; //日期时间格式
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
|
||||
private slots:
|
||||
void on_btnOk_clicked();
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public:
|
||||
//获取当前选择的开始时间和结束时间
|
||||
QString getStartDateTime() const;
|
||||
QString getEndDateTime() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
void setFormat(const QString &format);
|
||||
|
||||
};
|
||||
|
||||
//图形字体处理类
|
||||
class IconHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static IconHelper *Instance();
|
||||
explicit IconHelper(QObject *parent = 0);
|
||||
|
||||
//获取图形字体
|
||||
QFont getIconFont();
|
||||
|
||||
//设置图形字体到标签
|
||||
void setIcon(QLabel *lab, const QChar &str, quint32 size = 12);
|
||||
//设置图形字体到按钮
|
||||
void setIcon(QAbstractButton *btn, const QChar &str, quint32 size = 12);
|
||||
|
||||
//获取指定图形字体,可以指定文字大小,图片宽高,文字对齐
|
||||
QPixmap getPixmap(const QColor &color, const QChar &str, quint32 size = 12,
|
||||
quint32 pixWidth = 15, quint32 pixHeight = 15,
|
||||
int flags = Qt::AlignCenter);
|
||||
|
||||
//根据按钮获取该按钮对应的图标
|
||||
QPixmap getPixmap(QToolButton *btn, bool normal);
|
||||
QPixmap getPixmap(QToolButton *btn, int type);
|
||||
|
||||
//指定QFrame导航按钮样式,带图标
|
||||
void setStyle(QFrame *frame, QList<QToolButton *> btns, QList<int> pixChar,
|
||||
quint32 iconSize = 12, quint32 iconWidth = 15, quint32 iconHeight = 15,
|
||||
const QString &normalBgColor = "#2FC5A2",
|
||||
const QString &darkBgColor = "#3EA7E9",
|
||||
const QString &normalTextColor = "#EEEEEE",
|
||||
const QString &darkTextColor = "#FFFFFF");
|
||||
|
||||
//指定导航面板样式,不带图标
|
||||
static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3,
|
||||
const QString &borderColor = "#029FEA",
|
||||
const QString &normalBgColor = "#292F38",
|
||||
const QString &darkBgColor = "#1D2025",
|
||||
const QString &normalTextColor = "#54626F",
|
||||
const QString &darkTextColor = "#FDFDFD");
|
||||
|
||||
//移除导航面板样式,防止重复
|
||||
void removeStyle(QList<QToolButton *> btns);
|
||||
|
||||
//指定QWidget导航面板样式,带图标和效果切换
|
||||
void setStyle(QWidget *widget, QList<QToolButton *> btns, QList<int> pixChar,
|
||||
quint32 iconSize = 12, quint32 iconWidth = 15, quint32 iconHeight = 15,
|
||||
const QString &type = "left", int borderWidth = 3,
|
||||
const QString &borderColor = "#029FEA",
|
||||
const QString &normalBgColor = "#292F38",
|
||||
const QString &darkBgColor = "#1D2025",
|
||||
const QString &normalTextColor = "#54626F",
|
||||
const QString &darkTextColor = "#FDFDFD");
|
||||
|
||||
struct StyleColor {
|
||||
quint32 iconSize;
|
||||
quint32 iconWidth;
|
||||
quint32 iconHeight;
|
||||
quint32 borderWidth;
|
||||
QString type;
|
||||
QString borderColor;
|
||||
QString normalBgColor;
|
||||
QString normalTextColor;
|
||||
QString hoverBgColor;
|
||||
QString hoverTextColor;
|
||||
QString pressedBgColor;
|
||||
QString pressedTextColor;
|
||||
QString checkedBgColor;
|
||||
QString checkedTextColor;
|
||||
|
||||
StyleColor()
|
||||
{
|
||||
iconSize = 12;
|
||||
iconWidth = 15;
|
||||
iconHeight = 15;
|
||||
borderWidth = 3;
|
||||
type = "left";
|
||||
borderColor = "#029FEA";
|
||||
normalBgColor = "#292F38";
|
||||
normalTextColor = "#54626F";
|
||||
hoverBgColor = "#40444D";
|
||||
hoverTextColor = "#FDFDFD";
|
||||
pressedBgColor = "#404244";
|
||||
pressedTextColor = "#FDFDFD";
|
||||
checkedBgColor = "#44494F";
|
||||
checkedTextColor = "#FDFDFD";
|
||||
}
|
||||
};
|
||||
|
||||
//指定QWidget导航面板样式,带图标和效果切换+悬停颜色+按下颜色+选中颜色
|
||||
void setStyle(QWidget *widget, QList<QToolButton *> btns, QList<int> pixChar, const StyleColor &styleColor);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<IconHelper> self;
|
||||
|
||||
QFont iconFont; //图形字体
|
||||
QList<QToolButton *> btns; //按钮队列
|
||||
QList<QPixmap> pixNormal; //正常图片队列
|
||||
QList<QPixmap> pixDark; //加深图片队列
|
||||
QList<QPixmap> pixHover; //悬停图片队列
|
||||
QList<QPixmap> pixPressed; //按下图片队列
|
||||
QList<QPixmap> pixChecked; //选中图片队列
|
||||
};
|
||||
|
||||
//托盘图标类
|
||||
class TrayIcon : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static TrayIcon *Instance();
|
||||
explicit TrayIcon(QObject *parent = 0);
|
||||
|
||||
private:
|
||||
static QScopedPointer<TrayIcon> self;
|
||||
|
||||
QWidget *mainWidget; //对应所属主窗体
|
||||
QSystemTrayIcon *trayIcon; //托盘对象
|
||||
QMenu *menu; //右键菜单
|
||||
bool exitDirect; //是否直接退出
|
||||
|
||||
private slots:
|
||||
void iconIsActived(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置是否直接退出,如果不是直接退出则发送信号给主界面
|
||||
void setExitDirect(bool exitDirect);
|
||||
|
||||
//设置所属主窗体
|
||||
void setMainWidget(QWidget *mainWidget);
|
||||
|
||||
//显示消息
|
||||
void showMessage(const QString &title, const QString &msg,
|
||||
QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int msecs = 5000);
|
||||
|
||||
//设置图标
|
||||
void setIcon(const QString &strIcon);
|
||||
//设置提示信息
|
||||
void setToolTip(const QString &tip);
|
||||
//设置是否可见
|
||||
void setVisible(bool visible);
|
||||
//退出所有
|
||||
void closeAll();
|
||||
|
||||
Q_SIGNALS:
|
||||
void trayIconExit();
|
||||
};
|
||||
|
||||
|
||||
//全局静态方法类
|
||||
class QUIHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
//桌面宽度高度
|
||||
static int deskWidth();
|
||||
static int deskHeight();
|
||||
|
||||
//程序本身文件名称
|
||||
static QString appName();
|
||||
//程序当前所在路径
|
||||
static QString appPath();
|
||||
|
||||
//初始化随机数种子
|
||||
static void initRand();
|
||||
|
||||
//初始化数据库
|
||||
static void initDb(const QString &dbName);
|
||||
//初始化文件,不存在则拷贝
|
||||
static void initFile(const QString &sourceName, const QString &targetName);
|
||||
|
||||
//新建目录
|
||||
static void newDir(const QString &dirName);
|
||||
|
||||
//写入消息到额外的的消息日志文件
|
||||
static void writeInfo(const QString &info, const QString &filePath = "log");
|
||||
static void writeError(const QString &info, const QString &filePath = "log");
|
||||
|
||||
//设置全局样式
|
||||
static void setStyle(QUIWidget::Style style);
|
||||
static void setStyle(const QString &qssFile, QString &paletteColor, QString &textColor);
|
||||
static void setStyle(const QString &qssFile, QString &textColor,
|
||||
QString &panelColor, QString &borderColor,
|
||||
QString &normalColorStart, QString &normalColorEnd,
|
||||
QString &darkColorStart, QString &darkColorEnd,
|
||||
QString &highColor);
|
||||
|
||||
//根据QSS样式获取对应颜色值
|
||||
static void getQssColor(const QString &qss, QString &textColor,
|
||||
QString &panelColor, QString &borderColor,
|
||||
QString &normalColorStart, QString &normalColorEnd,
|
||||
QString &darkColorStart, QString &darkColorEnd,
|
||||
QString &highColor);
|
||||
|
||||
//九宫格图片 horzSplit-宫格1/3/7/9宽度 vertSplit-宫格1/3/7/9高度 dstWidth-目标图片宽度 dstHeight-目标图片高度
|
||||
static QPixmap ninePatch(const QString &picName, int horzSplit, int vertSplit, int dstWidth, int dstHeight);
|
||||
static QPixmap ninePatch(const QPixmap &pix, int horzSplit, int vertSplit, int dstWidth, int dstHeight);
|
||||
|
||||
//设置标签颜色
|
||||
static void setLabStyle(QLabel *lab, quint8 type);
|
||||
|
||||
//设置窗体居中显示
|
||||
static void setFormInCenter(QWidget *frm);
|
||||
//设置翻译文件
|
||||
static void setTranslator(const QString &qmFile = ":/image/qt_zh_CN.qm");
|
||||
//设置编码
|
||||
static void setCode();
|
||||
//设置延时
|
||||
static void sleep(int msec);
|
||||
//设置系统时间
|
||||
static void setSystemDateTime(const QString &year, const QString &month, const QString &day,
|
||||
const QString &hour, const QString &min, const QString &sec);
|
||||
//设置开机自启动
|
||||
static void runWithSystem(const QString &strName, const QString &strPath, bool autoRun = true);
|
||||
|
||||
//判断是否是IP地址
|
||||
static bool isIP(const QString &ip);
|
||||
|
||||
//判断是否是MAC地址
|
||||
static bool isMac(const QString &mac);
|
||||
|
||||
//判断是否是合法的电话号码
|
||||
static bool isTel(const QString &tel);
|
||||
|
||||
//判断是否是合法的邮箱地址
|
||||
static bool isEmail(const QString &email);
|
||||
|
||||
|
||||
//16进制字符串转10进制
|
||||
static int strHexToDecimal(const QString &strHex);
|
||||
|
||||
//10进制字符串转10进制
|
||||
static int strDecimalToDecimal(const QString &strDecimal);
|
||||
|
||||
//2进制字符串转10进制
|
||||
static int strBinToDecimal(const QString &strBin);
|
||||
|
||||
//16进制字符串转2进制字符串
|
||||
static QString strHexToStrBin(const QString &strHex);
|
||||
|
||||
//10进制转2进制字符串一个字节
|
||||
static QString decimalToStrBin1(int decimal);
|
||||
|
||||
//10进制转2进制字符串两个字节
|
||||
static QString decimalToStrBin2(int decimal);
|
||||
|
||||
//10进制转16进制字符串,补零.
|
||||
static QString decimalToStrHex(int decimal);
|
||||
|
||||
|
||||
//int转字节数组
|
||||
static QByteArray intToByte(int i);
|
||||
static QByteArray intToByteRec(int i);
|
||||
|
||||
//字节数组转int
|
||||
static int byteToInt(const QByteArray &data);
|
||||
static int byteToIntRec(const QByteArray &data);
|
||||
static quint32 byteToUInt(const QByteArray &data);
|
||||
static quint32 byteToUIntRec(const QByteArray &data);
|
||||
|
||||
//ushort转字节数组
|
||||
static QByteArray ushortToByte(ushort i);
|
||||
static QByteArray ushortToByteRec(ushort i);
|
||||
|
||||
//字节数组转ushort
|
||||
static int byteToUShort(const QByteArray &data);
|
||||
static int byteToUShortRec(const QByteArray &data);
|
||||
|
||||
//异或加密算法
|
||||
static QString getXorEncryptDecrypt(const QString &str, char key);
|
||||
|
||||
//异或校验
|
||||
static uchar getOrCode(const QByteArray &data);
|
||||
|
||||
//计算校验码
|
||||
static uchar getCheckCode(const QByteArray &data);
|
||||
|
||||
//字符串补全
|
||||
static QString getValue(quint8 value);
|
||||
|
||||
//CRC校验
|
||||
static quint16 getRevCrc_16(quint8 *data, int len, quint16 init, const quint16 *table);
|
||||
static quint16 getCrc_16(quint8 *data, int len, quint16 init, const quint16 *table);
|
||||
static quint16 getModbus16(quint8 *data, int len);
|
||||
static QByteArray getCRCCode(const QByteArray &data);
|
||||
|
||||
|
||||
//字节数组转Ascii字符串
|
||||
static QString byteArrayToAsciiStr(const QByteArray &data);
|
||||
|
||||
//16进制字符串转字节数组
|
||||
static QByteArray hexStrToByteArray(const QString &str);
|
||||
static char convertHexChar(char ch);
|
||||
|
||||
//Ascii字符串转字节数组
|
||||
static QByteArray asciiStrToByteArray(const QString &str);
|
||||
|
||||
//字节数组转16进制字符串
|
||||
static QString byteArrayToHexStr(const QByteArray &data);
|
||||
|
||||
//获取保存的文件
|
||||
static QString getSaveName(const QString &filter, QString defaultDir = QCoreApplication::applicationDirPath());
|
||||
|
||||
//获取选择的文件
|
||||
static QString getFileName(const QString &filter, QString defaultDir = QCoreApplication::applicationDirPath());
|
||||
|
||||
//获取选择的文件集合
|
||||
static QStringList getFileNames(const QString &filter, QString defaultDir = QCoreApplication::applicationDirPath());
|
||||
|
||||
//获取选择的目录
|
||||
static QString getFolderName();
|
||||
|
||||
//获取文件名,含拓展名
|
||||
static QString getFileNameWithExtension(const QString &strFilePath);
|
||||
|
||||
//获取选择文件夹中的文件
|
||||
static QStringList getFolderFileNames(const QStringList &filter);
|
||||
|
||||
//文件夹是否存在
|
||||
static bool folderIsExist(const QString &strFolder);
|
||||
|
||||
//文件是否存在
|
||||
static bool fileIsExist(const QString &strFile);
|
||||
|
||||
//复制文件
|
||||
static bool copyFile(const QString &sourceFile, const QString &targetFile);
|
||||
|
||||
//删除文件夹下所有文件
|
||||
static void deleteDirectory(const QString &path);
|
||||
|
||||
//判断IP地址及端口是否在线
|
||||
static bool ipLive(const QString &ip, int port, int timeout = 1000);
|
||||
|
||||
//获取网页所有源代码
|
||||
static QString getHtml(const QString &url);
|
||||
|
||||
//获取本机公网IP地址
|
||||
static QString getNetIP(const QString &webCode);
|
||||
|
||||
//获取本机IP
|
||||
static QString getLocalIP();
|
||||
|
||||
//Url地址转为IP地址
|
||||
static QString urlToIP(const QString &url);
|
||||
|
||||
//判断是否通外网
|
||||
static bool isWebOk();
|
||||
|
||||
|
||||
//弹出消息框
|
||||
static void showMessageBoxInfo(const QString &info, int closeSec = 0, bool exec = false);
|
||||
//弹出错误框
|
||||
static void showMessageBoxError(const QString &info, int closeSec = 0, bool exec = false);
|
||||
//弹出询问框
|
||||
static int showMessageBoxQuestion(const QString &info);
|
||||
|
||||
//弹出+隐藏右下角信息框
|
||||
static void showTipBox(const QString &title, const QString &tip, bool fullScreen = false,
|
||||
bool center = true, int closeSec = 0);
|
||||
static void hideTipBox();
|
||||
|
||||
//弹出输入框
|
||||
static QString showInputBox(const QString &title, int type = 0, int closeSec = 0,
|
||||
const QString &placeholderText = QString(), bool pwd = false,
|
||||
const QString &defaultValue = QString());
|
||||
|
||||
//弹出日期选择框
|
||||
static void showDateSelect(QString &dateStart, QString &dateEnd, const QString &format = "yyyy-MM-dd");
|
||||
|
||||
|
||||
//设置按钮样式
|
||||
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 setProgressBarQss(QProgressBar *bar,
|
||||
int barHeight = 8, //进度条高度
|
||||
int barRadius = 5, //进度条半径
|
||||
int fontSize = 9, //文字字号
|
||||
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", //指示器颜色
|
||||
const QString &textColor = "#000000"); //文字颜色
|
||||
|
||||
//设置单选框样式
|
||||
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"); //指示器按下颜色
|
||||
};
|
||||
|
||||
//全局变量控制
|
||||
class QUIConfig
|
||||
{
|
||||
public:
|
||||
//全局图标
|
||||
static QChar IconMain; //标题栏左上角图标
|
||||
static QChar IconMenu; //下拉菜单图标
|
||||
static QChar IconMin; //最小化图标
|
||||
static QChar IconMax; //最大化图标
|
||||
static QChar IconNormal; //还原图标
|
||||
static QChar IconClose; //关闭图标
|
||||
|
||||
static QString FontName; //全局字体名称
|
||||
static int FontSize; //全局字体大小
|
||||
|
||||
//样式表颜色值
|
||||
static QString TextColor; //文字颜色
|
||||
static QString PanelColor; //面板颜色
|
||||
static QString BorderColor; //边框颜色
|
||||
static QString NormalColorStart;//正常状态开始颜色
|
||||
static QString NormalColorEnd; //正常状态结束颜色
|
||||
static QString DarkColorStart; //加深状态开始颜色
|
||||
static QString DarkColorEnd; //加深状态结束颜色
|
||||
static QString HighColor; //高亮颜色
|
||||
};
|
||||
|
||||
#endif // QUIWIDGET_H
|
||||
36
comtool/comtool.pro
Normal file
36
comtool/comtool.pro
Normal file
@@ -0,0 +1,36 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2016-09-19T22:25:56
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui network
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = comtool
|
||||
TEMPLATE = app
|
||||
MOC_DIR = temp/moc
|
||||
RCC_DIR = temp/rcc
|
||||
UI_DIR = temp/ui
|
||||
OBJECTS_DIR = temp/obj
|
||||
DESTDIR = bin
|
||||
RC_FILE = other/main.rc
|
||||
|
||||
SOURCES += main.cpp
|
||||
HEADERS += head.h
|
||||
RESOURCES += other/main.qrc
|
||||
CONFIG += warn_off
|
||||
|
||||
include ($$PWD/api/api.pri)
|
||||
include ($$PWD/form/form.pri)
|
||||
include ($$PWD/qextserialport/qextserialport.pri)
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
INCLUDEPATH += $$PWD/api
|
||||
INCLUDEPATH += $$PWD/form
|
||||
INCLUDEPATH += $$PWD/qextserialport
|
||||
|
||||
#INCLUDEPATH += /usr/local/openssl-1.0.2m-h3-gcc-4.9.2/include
|
||||
#LIBS += -L/usr/local/openssl-1.0.2m-h3-gcc-4.9.2/lib -lssl -lcrypto
|
||||
#LIBS += -L/usr/local/h3_rootfsv -lXdmcp
|
||||
1
comtool/file/device.txt
Normal file
1
comtool/file/device.txt
Normal file
@@ -0,0 +1 @@
|
||||
01 03 00 00 00 06 C5 C8;01 03 0C 00 01 00 01 00 00 00 01 00 01 00 01 37 DC
|
||||
17
comtool/file/send.txt
Normal file
17
comtool/file/send.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
16 FF 01 01 E0 E1
|
||||
16 FF 01 01 E1 E2
|
||||
16 01 02 DF BC 16 01 02 DF BC 16 01 02 DF BC 12 13 14 15
|
||||
16 00 00 04 D0 F0 F1 65 C4
|
||||
16 00 00 04 D0 05 AB 5A C4
|
||||
16 01 10 02 F0 03 06 16 01 11 02 F0 03 06 16 01 12 02 F0 03 06 16 01 13 02 F0 03 06 16 01
|
||||
14 02 F0 03 06 16 01 15 02 F0 03 06 16 01 16 02 F0 03 06
|
||||
16 11 01 03 E8 01 10 0E
|
||||
16 11 01 03 E8 01 12 10
|
||||
16 11 01 03 E8 01 14 12
|
||||
16 11 01 03 E8 01 15 13
|
||||
DISARMEDALL
|
||||
BURGLARY 012
|
||||
BYPASS 012
|
||||
DISARMED 012
|
||||
16 00 01 01 D1 D3
|
||||
16 01 11 11
|
||||
8
comtool/form/form.pri
Normal file
8
comtool/form/form.pri
Normal file
@@ -0,0 +1,8 @@
|
||||
FORMS += \
|
||||
$$PWD/frmcomtool.ui
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/frmcomtool.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/frmcomtool.cpp
|
||||
584
comtool/form/frmcomtool.cpp
Normal file
584
comtool/form/frmcomtool.cpp
Normal file
@@ -0,0 +1,584 @@
|
||||
#include "frmcomtool.h"
|
||||
#include "ui_frmcomtool.h"
|
||||
#include "quiwidget.h"
|
||||
|
||||
frmComTool::frmComTool(QWidget *parent) : QWidget(parent), ui(new Ui::frmComTool)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
this->initConfig();
|
||||
QUIHelper::setFormInCenter(this);
|
||||
}
|
||||
|
||||
frmComTool::~frmComTool()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmComTool::initForm()
|
||||
{
|
||||
comOk = false;
|
||||
com = 0;
|
||||
sleepTime = 10;
|
||||
receiveCount = 0;
|
||||
sendCount = 0;
|
||||
isShow = true;
|
||||
|
||||
ui->cboxSendInterval->addItems(App::Intervals);
|
||||
ui->cboxData->addItems(App::Datas);
|
||||
|
||||
//读取数据
|
||||
timerRead = new QTimer(this);
|
||||
timerRead->setInterval(100);
|
||||
connect(timerRead, SIGNAL(timeout()), this, SLOT(readData()));
|
||||
|
||||
//发送数据
|
||||
timerSend = new QTimer(this);
|
||||
connect(timerSend, SIGNAL(timeout()), this, SLOT(sendData()));
|
||||
connect(ui->btnSend, SIGNAL(clicked()), this, SLOT(sendData()));
|
||||
|
||||
//保存数据
|
||||
timerSave = new QTimer(this);
|
||||
connect(timerSave, SIGNAL(timeout()), this, SLOT(saveData()));
|
||||
connect(ui->btnSave, SIGNAL(clicked()), this, SLOT(saveData()));
|
||||
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
changeEnable(false);
|
||||
|
||||
tcpOk = false;
|
||||
socket = new QTcpSocket(this);
|
||||
socket->abort();
|
||||
connect(socket, SIGNAL(readyRead()), this, SLOT(readDataNet()));
|
||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(readErrorNet()));
|
||||
|
||||
timerConnect = new QTimer(this);
|
||||
connect(timerConnect, SIGNAL(timeout()), this, SLOT(connectNet()));
|
||||
timerConnect->setInterval(3000);
|
||||
timerConnect->start();
|
||||
|
||||
#ifdef __arm__
|
||||
ui->widgetRight->setFixedWidth(280);
|
||||
#endif
|
||||
}
|
||||
|
||||
void frmComTool::initConfig()
|
||||
{
|
||||
QStringList comList;
|
||||
for (int i = 1; i <= 20; i++) {
|
||||
comList << QString("COM%1").arg(i);
|
||||
}
|
||||
|
||||
comList << "ttyUSB0" << "ttyS0" << "ttyS1" << "ttyS2" << "ttyS3" << "ttyS4";
|
||||
comList << "ttymxc1" << "ttymxc2" << "ttymxc3" << "ttymxc4";
|
||||
comList << "ttySAC1" << "ttySAC2" << "ttySAC3" << "ttySAC4";
|
||||
ui->cboxPortName->addItems(comList);
|
||||
ui->cboxPortName->setCurrentIndex(ui->cboxPortName->findText(App::PortName));
|
||||
connect(ui->cboxPortName, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList baudList;
|
||||
baudList << "50" << "75" << "100" << "134" << "150" << "200" << "300" << "600" << "1200"
|
||||
<< "1800" << "2400" << "4800" << "9600" << "14400" << "19200" << "38400"
|
||||
<< "56000" << "57600" << "76800" << "115200" << "128000" << "256000";
|
||||
|
||||
ui->cboxBaudRate->addItems(baudList);
|
||||
ui->cboxBaudRate->setCurrentIndex(ui->cboxBaudRate->findText(QString::number(App::BaudRate)));
|
||||
connect(ui->cboxBaudRate, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList dataBitsList;
|
||||
dataBitsList << "5" << "6" << "7" << "8";
|
||||
|
||||
ui->cboxDataBit->addItems(dataBitsList);
|
||||
ui->cboxDataBit->setCurrentIndex(ui->cboxDataBit->findText(QString::number(App::DataBit)));
|
||||
connect(ui->cboxDataBit, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList parityList;
|
||||
parityList << "无" << "奇" << "偶";
|
||||
#ifdef Q_OS_WIN
|
||||
parityList << "标志";
|
||||
#endif
|
||||
parityList << "空格";
|
||||
|
||||
ui->cboxParity->addItems(parityList);
|
||||
ui->cboxParity->setCurrentIndex(ui->cboxParity->findText(App::Parity));
|
||||
connect(ui->cboxParity, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList stopBitsList;
|
||||
stopBitsList << "1";
|
||||
#ifdef Q_OS_WIN
|
||||
stopBitsList << "1.5";
|
||||
#endif
|
||||
stopBitsList << "2";
|
||||
|
||||
ui->cboxStopBit->addItems(stopBitsList);
|
||||
ui->cboxStopBit->setCurrentIndex(ui->cboxStopBit->findText(QString::number(App::StopBit)));
|
||||
connect(ui->cboxStopBit, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckHexSend->setChecked(App::HexSend);
|
||||
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckHexReceive->setChecked(App::HexReceive);
|
||||
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckDebug->setChecked(App::Debug);
|
||||
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoClear->setChecked(App::AutoClear);
|
||||
connect(ui->ckAutoClear, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoSend->setChecked(App::AutoSend);
|
||||
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoSave->setChecked(App::AutoSave);
|
||||
connect(ui->ckAutoSave, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList sendInterval;
|
||||
QStringList saveInterval;
|
||||
sendInterval << "100" << "300" << "500";
|
||||
|
||||
for (int i = 1000; i <= 10000; i = i + 1000) {
|
||||
sendInterval << QString::number(i);
|
||||
saveInterval << QString::number(i);
|
||||
}
|
||||
|
||||
ui->cboxSendInterval->addItems(sendInterval);
|
||||
ui->cboxSaveInterval->addItems(saveInterval);
|
||||
|
||||
ui->cboxSendInterval->setCurrentIndex(ui->cboxSendInterval->findText(QString::number(App::SendInterval)));
|
||||
connect(ui->cboxSendInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
ui->cboxSaveInterval->setCurrentIndex(ui->cboxSaveInterval->findText(QString::number(App::SaveInterval)));
|
||||
connect(ui->cboxSaveInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
timerSend->setInterval(App::SendInterval);
|
||||
timerSave->setInterval(App::SaveInterval);
|
||||
|
||||
if (App::AutoSend) {
|
||||
timerSend->start();
|
||||
}
|
||||
|
||||
if (App::AutoSave) {
|
||||
timerSave->start();
|
||||
}
|
||||
|
||||
//串口转网络部分
|
||||
ui->cboxMode->setCurrentIndex(ui->cboxMode->findText(App::Mode));
|
||||
connect(ui->cboxMode, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->txtServerIP->setText(App::ServerIP);
|
||||
connect(ui->txtServerIP, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->txtServerPort->setText(QString::number(App::ServerPort));
|
||||
connect(ui->txtServerPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->txtListenPort->setText(QString::number(App::ListenPort));
|
||||
connect(ui->txtListenPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
|
||||
|
||||
QStringList values;
|
||||
values << "0" << "10" << "50";
|
||||
|
||||
for (int i = 100; i < 1000; i = i + 100) {
|
||||
values << QString("%1").arg(i);
|
||||
}
|
||||
|
||||
ui->cboxSleepTime->addItems(values);
|
||||
|
||||
ui->cboxSleepTime->setCurrentIndex(ui->cboxSleepTime->findText(QString::number(App::SleepTime)));
|
||||
connect(ui->cboxSleepTime, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoConnect->setChecked(App::AutoConnect);
|
||||
connect(ui->ckAutoConnect, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
}
|
||||
|
||||
void frmComTool::saveConfig()
|
||||
{
|
||||
App::PortName = ui->cboxPortName->currentText();
|
||||
App::BaudRate = ui->cboxBaudRate->currentText().toInt();
|
||||
App::DataBit = ui->cboxDataBit->currentText().toInt();
|
||||
App::Parity = ui->cboxParity->currentText();
|
||||
App::StopBit = ui->cboxStopBit->currentText().toDouble();
|
||||
|
||||
App::HexSend = ui->ckHexSend->isChecked();
|
||||
App::HexReceive = ui->ckHexReceive->isChecked();
|
||||
App::Debug = ui->ckDebug->isChecked();
|
||||
App::AutoClear = ui->ckAutoClear->isChecked();
|
||||
|
||||
App::AutoSend = ui->ckAutoSend->isChecked();
|
||||
App::AutoSave = ui->ckAutoSave->isChecked();
|
||||
|
||||
int sendInterval = ui->cboxSendInterval->currentText().toInt();
|
||||
if (sendInterval != App::SendInterval) {
|
||||
App::SendInterval = sendInterval;
|
||||
timerSend->setInterval(App::SendInterval);
|
||||
}
|
||||
|
||||
int saveInterval = ui->cboxSaveInterval->currentText().toInt();
|
||||
if (saveInterval != App::SaveInterval) {
|
||||
App::SaveInterval = saveInterval;
|
||||
timerSave->setInterval(App::SaveInterval);
|
||||
}
|
||||
|
||||
App::Mode = ui->cboxMode->currentText();
|
||||
App::ServerIP = ui->txtServerIP->text().trimmed();
|
||||
App::ServerPort = ui->txtServerPort->text().toInt();
|
||||
App::ListenPort = ui->txtListenPort->text().toInt();
|
||||
App::SleepTime = ui->cboxSleepTime->currentText().toInt();
|
||||
App::AutoConnect = ui->ckAutoConnect->isChecked();
|
||||
|
||||
App::writeConfig();
|
||||
}
|
||||
|
||||
void frmComTool::changeEnable(bool b)
|
||||
{
|
||||
ui->cboxBaudRate->setEnabled(!b);
|
||||
ui->cboxDataBit->setEnabled(!b);
|
||||
ui->cboxParity->setEnabled(!b);
|
||||
ui->cboxPortName->setEnabled(!b);
|
||||
ui->cboxStopBit->setEnabled(!b);
|
||||
ui->btnSend->setEnabled(b);
|
||||
ui->ckAutoSend->setEnabled(b);
|
||||
ui->ckAutoSave->setEnabled(b);
|
||||
}
|
||||
|
||||
void frmComTool::append(int type, const QString &data, bool clear)
|
||||
{
|
||||
static int currentCount = 0;
|
||||
static int maxCount = 100;
|
||||
|
||||
if (clear) {
|
||||
ui->txtMain->clear();
|
||||
currentCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentCount >= maxCount) {
|
||||
ui->txtMain->clear();
|
||||
currentCount = 0;
|
||||
}
|
||||
|
||||
if (!isShow) {
|
||||
return;
|
||||
}
|
||||
|
||||
//过滤回车换行符
|
||||
QString strData = data;
|
||||
strData = strData.replace("\r", "");
|
||||
strData = strData.replace("\n", "");
|
||||
|
||||
//不同类型不同颜色显示
|
||||
QString strType;
|
||||
if (type == 0) {
|
||||
strType = "串口发送 >>";
|
||||
ui->txtMain->setTextColor(QColor("dodgerblue"));
|
||||
} else if (type == 1) {
|
||||
strType = "串口接收 <<";
|
||||
ui->txtMain->setTextColor(QColor("red"));
|
||||
} else if (type == 2) {
|
||||
strType = "处理延时 >>";
|
||||
ui->txtMain->setTextColor(QColor("gray"));
|
||||
} else if (type == 3) {
|
||||
strType = "正在校验 >>";
|
||||
ui->txtMain->setTextColor(QColor("green"));
|
||||
} else if (type == 4) {
|
||||
strType = "网络发送 >>";
|
||||
ui->txtMain->setTextColor(QColor(24, 189, 155));
|
||||
} else if (type == 5) {
|
||||
strType = "网络接收 <<";
|
||||
ui->txtMain->setTextColor(QColor(255, 107, 107));
|
||||
} else if (type == 6) {
|
||||
strType = "提示信息 >>";
|
||||
ui->txtMain->setTextColor(QColor(100, 184, 255));
|
||||
}
|
||||
|
||||
strData = QString("时间[%1] %2 %3").arg(TIMEMS).arg(strType).arg(strData);
|
||||
ui->txtMain->append(strData);
|
||||
currentCount++;
|
||||
}
|
||||
|
||||
void frmComTool::readData()
|
||||
{
|
||||
if (com->bytesAvailable() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QUIHelper::sleep(sleepTime);
|
||||
QByteArray data = com->readAll();
|
||||
int dataLen = data.length();
|
||||
if (dataLen <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isShow) {
|
||||
QString buffer;
|
||||
if (ui->ckHexReceive->isChecked()) {
|
||||
buffer = QUIHelper::byteArrayToHexStr(data);
|
||||
} else {
|
||||
//buffer = QUIHelper::byteArrayToAsciiStr(data);
|
||||
buffer = QString::fromLocal8Bit(data);
|
||||
}
|
||||
|
||||
//启用调试则模拟调试数据
|
||||
if (ui->ckDebug->isChecked()) {
|
||||
int count = App::Keys.count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (buffer.startsWith(App::Keys.at(i))) {
|
||||
sendData(App::Values.at(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
append(1, buffer);
|
||||
receiveCount = receiveCount + data.size();
|
||||
ui->btnReceiveCount->setText(QString("接收 : %1 字节").arg(receiveCount));
|
||||
|
||||
//启用网络转发则调用网络发送数据
|
||||
if (tcpOk) {
|
||||
socket->write(data);
|
||||
append(4, QString(buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::sendData()
|
||||
{
|
||||
QString str = ui->cboxData->currentText();
|
||||
if (str.isEmpty()) {
|
||||
ui->cboxData->setFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
sendData(str);
|
||||
|
||||
if (ui->ckAutoClear->isChecked()) {
|
||||
ui->cboxData->setCurrentIndex(-1);
|
||||
ui->cboxData->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::sendData(QString data)
|
||||
{
|
||||
if (com == 0 || !com->isOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//短信猫调试
|
||||
if (data.startsWith("AT")) {
|
||||
data += "\r";
|
||||
}
|
||||
|
||||
QByteArray buffer;
|
||||
|
||||
if (ui->ckHexSend->isChecked()) {
|
||||
buffer = QUIHelper::hexStrToByteArray(data);
|
||||
} else {
|
||||
buffer = QUIHelper::asciiStrToByteArray(data);
|
||||
}
|
||||
|
||||
com->write(buffer);
|
||||
append(0, data);
|
||||
sendCount = sendCount + buffer.size();
|
||||
ui->btnSendCount->setText(QString("发送 : %1 字节").arg(sendCount));
|
||||
}
|
||||
|
||||
void frmComTool::saveData()
|
||||
{
|
||||
QString tempData = ui->txtMain->toPlainText();
|
||||
|
||||
if (tempData == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QString name = now.toString("yyyy-MM-dd-HH-mm-ss");
|
||||
QString fileName = QString("%1/%2.txt").arg(QUIHelper::appPath()).arg(name);
|
||||
|
||||
QFile file(fileName);
|
||||
file.open(QFile::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
out << tempData;
|
||||
file.close();
|
||||
|
||||
on_btnClear_clicked();
|
||||
}
|
||||
|
||||
void frmComTool::on_btnOpen_clicked()
|
||||
{
|
||||
if (ui->btnOpen->text() == "打开串口") {
|
||||
com = new QextSerialPort(ui->cboxPortName->currentText(), QextSerialPort::Polling);
|
||||
comOk = com->open(QIODevice::ReadWrite);
|
||||
|
||||
if (comOk) {
|
||||
//清空缓冲区
|
||||
com->flush();
|
||||
//设置波特率
|
||||
com->setBaudRate((BaudRateType)ui->cboxBaudRate->currentText().toInt());
|
||||
//设置数据位
|
||||
com->setDataBits((DataBitsType)ui->cboxDataBit->currentText().toInt());
|
||||
//设置校验位
|
||||
com->setParity((ParityType)ui->cboxParity->currentIndex());
|
||||
//设置停止位
|
||||
com->setStopBits((StopBitsType)ui->cboxStopBit->currentIndex());
|
||||
com->setFlowControl(FLOW_OFF);
|
||||
com->setTimeout(10);
|
||||
|
||||
changeEnable(true);
|
||||
ui->btnOpen->setText("关闭串口");
|
||||
timerRead->start();
|
||||
}
|
||||
} else {
|
||||
timerRead->stop();
|
||||
com->close();
|
||||
com->deleteLater();
|
||||
|
||||
changeEnable(false);
|
||||
ui->btnOpen->setText("打开串口");
|
||||
on_btnClear_clicked();
|
||||
comOk = false;
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_btnSendCount_clicked()
|
||||
{
|
||||
sendCount = 0;
|
||||
ui->btnSendCount->setText("发送 : 0 字节");
|
||||
}
|
||||
|
||||
void frmComTool::on_btnReceiveCount_clicked()
|
||||
{
|
||||
receiveCount = 0;
|
||||
ui->btnReceiveCount->setText("接收 : 0 字节");
|
||||
}
|
||||
|
||||
void frmComTool::on_btnStopShow_clicked()
|
||||
{
|
||||
if (ui->btnStopShow->text() == "停止显示") {
|
||||
isShow = false;
|
||||
ui->btnStopShow->setText("开始显示");
|
||||
} else {
|
||||
isShow = true;
|
||||
ui->btnStopShow->setText("停止显示");
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_btnData_clicked()
|
||||
{
|
||||
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg("send.txt");
|
||||
QFile file(fileName);
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ui->btnData->text() == "管理数据") {
|
||||
ui->txtMain->setReadOnly(false);
|
||||
ui->txtMain->clear();
|
||||
file.open(QFile::ReadOnly | QIODevice::Text);
|
||||
QTextStream in(&file);
|
||||
ui->txtMain->setText(in.readAll());
|
||||
file.close();
|
||||
ui->btnData->setText("保存数据");
|
||||
} else {
|
||||
ui->txtMain->setReadOnly(true);
|
||||
file.open(QFile::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
out << ui->txtMain->toPlainText();
|
||||
file.close();
|
||||
ui->txtMain->clear();
|
||||
ui->btnData->setText("管理数据");
|
||||
App::readSendData();
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_btnClear_clicked()
|
||||
{
|
||||
append(0, "", true);
|
||||
}
|
||||
|
||||
void frmComTool::on_btnStart_clicked()
|
||||
{
|
||||
if (ui->btnStart->text() == "启动") {
|
||||
if (App::ServerIP == "" || App::ServerPort == 0) {
|
||||
append(6, "IP地址和远程端口不能为空");
|
||||
return;
|
||||
}
|
||||
|
||||
socket->connectToHost(App::ServerIP, App::ServerPort);
|
||||
if (socket->waitForConnected(100)) {
|
||||
ui->btnStart->setText("停止");
|
||||
append(6, "连接服务器成功");
|
||||
tcpOk = true;
|
||||
}
|
||||
} else {
|
||||
socket->disconnectFromHost();
|
||||
if (socket->state() == QAbstractSocket::UnconnectedState || socket->waitForDisconnected(100)) {
|
||||
ui->btnStart->setText("启动");
|
||||
append(6, "断开服务器成功");
|
||||
tcpOk = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_ckAutoSend_stateChanged(int arg1)
|
||||
{
|
||||
if (arg1 == 0) {
|
||||
ui->cboxSendInterval->setEnabled(false);
|
||||
timerSend->stop();
|
||||
} else {
|
||||
ui->cboxSendInterval->setEnabled(true);
|
||||
timerSend->start();
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::on_ckAutoSave_stateChanged(int arg1)
|
||||
{
|
||||
if (arg1 == 0) {
|
||||
ui->cboxSaveInterval->setEnabled(false);
|
||||
timerSave->stop();
|
||||
} else {
|
||||
ui->cboxSaveInterval->setEnabled(true);
|
||||
timerSave->start();
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::connectNet()
|
||||
{
|
||||
if (!tcpOk && App::AutoConnect && ui->btnStart->text() == "启动") {
|
||||
if (App::ServerIP != "" && App::ServerPort != 0) {
|
||||
socket->connectToHost(App::ServerIP, App::ServerPort);
|
||||
if (socket->waitForConnected(100)) {
|
||||
ui->btnStart->setText("停止");
|
||||
append(6, "连接服务器成功");
|
||||
tcpOk = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::readDataNet()
|
||||
{
|
||||
if (socket->bytesAvailable() > 0) {
|
||||
QUIHelper::sleep(App::SleepTime);
|
||||
QByteArray data = socket->readAll();
|
||||
|
||||
QString buffer;
|
||||
if (ui->ckHexReceive->isChecked()) {
|
||||
buffer = QUIHelper::byteArrayToHexStr(data);
|
||||
} else {
|
||||
buffer = QUIHelper::byteArrayToAsciiStr(data);
|
||||
}
|
||||
|
||||
append(5, buffer);
|
||||
|
||||
//将收到的网络数据转发给串口
|
||||
if (comOk) {
|
||||
com->write(data);
|
||||
append(0, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmComTool::readErrorNet()
|
||||
{
|
||||
ui->btnStart->setText("启动");
|
||||
append(6, QString("连接服务器失败,%1").arg(socket->errorString()));
|
||||
socket->disconnectFromHost();
|
||||
tcpOk = false;
|
||||
}
|
||||
68
comtool/form/frmcomtool.h
Normal file
68
comtool/form/frmcomtool.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifndef FRMCOMTOOL_H
|
||||
#define FRMCOMTOOL_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "qtcpsocket.h"
|
||||
#include "qextserialport.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class frmComTool;
|
||||
}
|
||||
|
||||
class frmComTool : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmComTool(QWidget *parent = 0);
|
||||
~frmComTool();
|
||||
|
||||
private:
|
||||
Ui::frmComTool *ui;
|
||||
|
||||
bool comOk; //串口是否打开
|
||||
QextSerialPort *com; //串口通信对象
|
||||
QTimer *timerRead; //定时读取串口数据
|
||||
QTimer *timerSend; //定时发送串口数据
|
||||
QTimer *timerSave; //定时保存串口数据
|
||||
|
||||
int sleepTime; //接收延时时间
|
||||
int sendCount; //发送数据计数
|
||||
int receiveCount; //接收数据计数
|
||||
bool isShow; //是否显示数据
|
||||
|
||||
bool tcpOk; //网络是否正常
|
||||
QTcpSocket *socket; //网络连接对象
|
||||
QTimer *timerConnect; //定时器重连
|
||||
|
||||
private slots:
|
||||
void initForm(); //初始化窗体数据
|
||||
void initConfig(); //初始化配置文件
|
||||
void saveConfig(); //保存配置文件
|
||||
void readData(); //读取串口数据
|
||||
void sendData(); //发送串口数据
|
||||
void sendData(QString data);//发送串口数据带参数
|
||||
void saveData(); //保存串口数据
|
||||
|
||||
void changeEnable(bool b); //改变状态
|
||||
void append(int type, const QString &data, bool clear = false);
|
||||
|
||||
private slots:
|
||||
void connectNet();
|
||||
void readDataNet();
|
||||
void readErrorNet();
|
||||
|
||||
private slots:
|
||||
void on_btnOpen_clicked();
|
||||
void on_btnStopShow_clicked();
|
||||
void on_btnSendCount_clicked();
|
||||
void on_btnReceiveCount_clicked();
|
||||
void on_btnClear_clicked();
|
||||
void on_btnData_clicked();
|
||||
void on_btnStart_clicked();
|
||||
void on_ckAutoSend_stateChanged(int arg1);
|
||||
void on_ckAutoSave_stateChanged(int arg1);
|
||||
};
|
||||
|
||||
#endif // FRMCOMTOOL_H
|
||||
473
comtool/form/frmcomtool.ui
Normal file
473
comtool/form/frmcomtool.ui
Normal file
@@ -0,0 +1,473 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmComTool</class>
|
||||
<widget class="QWidget" name="frmComTool">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="txtMain">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<widget class="QWidget" name="widgetRight" native="true">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<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="QFrame" name="frameTop">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labPortName">
|
||||
<property name="text">
|
||||
<string>串口号</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cboxPortName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labBaudRate">
|
||||
<property name="text">
|
||||
<string>波特率</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cboxBaudRate">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labDataBit">
|
||||
<property name="text">
|
||||
<string>数据位</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cboxDataBit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labParity">
|
||||
<property name="text">
|
||||
<string>校验位</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="cboxParity">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labStopBit">
|
||||
<property name="text">
|
||||
<string>停止位</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="cboxStopBit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnOpen">
|
||||
<property name="text">
|
||||
<string>打开串口</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="tabPosition">
|
||||
<enum>QTabWidget::South</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>串口配置</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="ckHexSend">
|
||||
<property name="text">
|
||||
<string>Hex发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="ckHexReceive">
|
||||
<property name="text">
|
||||
<string>Hex接收</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="ckDebug">
|
||||
<property name="text">
|
||||
<string>模拟设备</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="ckAutoClear">
|
||||
<property name="text">
|
||||
<string>自动清空</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="ckAutoSend">
|
||||
<property name="text">
|
||||
<string>自动发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cboxSendInterval">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="ckAutoSave">
|
||||
<property name="text">
|
||||
<string>自动保存</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cboxSaveInterval">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnSendCount">
|
||||
<property name="text">
|
||||
<string>发送 : 0 字节</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnReceiveCount">
|
||||
<property name="text">
|
||||
<string>接收 : 0 字节</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnStopShow">
|
||||
<property name="text">
|
||||
<string>停止显示</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnSave">
|
||||
<property name="text">
|
||||
<string>保存数据</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnData">
|
||||
<property name="text">
|
||||
<string>管理数据</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnClear">
|
||||
<property name="text">
|
||||
<string>清空数据</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>2</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>网络配置</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labListenPort">
|
||||
<property name="text">
|
||||
<string>监听端口</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labServerIP">
|
||||
<property name="text">
|
||||
<string>远程地址</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="cboxSleepTime"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="txtServerIP">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labServerPort">
|
||||
<property name="text">
|
||||
<string>远程端口</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="txtServerPort">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labSleepTime">
|
||||
<property name="text">
|
||||
<string>延时时间</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="txtListenPort"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labMode">
|
||||
<property name="text">
|
||||
<string>转换模式</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cboxMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tcp_Client</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tcp_Server</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Udp_Client</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Udp_Server</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="btnStart">
|
||||
<property name="text">
|
||||
<string>启动</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>59</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="ckAutoConnect">
|
||||
<property name="text">
|
||||
<string>自动重连网络</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<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="QComboBox" name="cboxData">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="duplicatesEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSend">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
11
comtool/head.h
Normal file
11
comtool/head.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QtNetwork>
|
||||
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
|
||||
#include <QtWidgets>
|
||||
#endif
|
||||
|
||||
#include "app.h"
|
||||
|
||||
#pragma execution_character_set("utf-8")
|
||||
31
comtool/main.cpp
Normal file
31
comtool/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "frmcomtool.h"
|
||||
#include "quiwidget.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setWindowIcon(QIcon(":/main.ico"));
|
||||
|
||||
QFont font;
|
||||
font.setFamily(QUIConfig::FontName);
|
||||
font.setPixelSize(QUIConfig::FontSize);
|
||||
a.setFont(font);
|
||||
|
||||
//设置编码以及加载中文翻译文件
|
||||
QUIHelper::setCode();
|
||||
QUIHelper::setTranslator(":/qt_zh_CN.qm");
|
||||
QUIHelper::setTranslator(":/widgets.qm");
|
||||
QUIHelper::initRand();
|
||||
|
||||
App::Intervals << "1" << "10" << "20" << "50" << "100" << "200" << "300" << "500" << "1000" << "1500" << "2000" << "3000" << "5000" << "10000";
|
||||
App::ConfigFile = QString("%1/%2.ini").arg(QUIHelper::appPath()).arg(QUIHelper::appName());
|
||||
App::readConfig();
|
||||
App::readSendData();
|
||||
App::readDeviceData();
|
||||
|
||||
frmComTool w;
|
||||
w.setWindowTitle("串口调试助手V2019 QQ: 517216493");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
BIN
comtool/other/main.ico
Normal file
BIN
comtool/other/main.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
5
comtool/other/main.qrc
Normal file
5
comtool/other/main.qrc
Normal file
@@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.ico</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
1
comtool/other/main.rc
Normal file
1
comtool/other/main.rc
Normal file
@@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "main.ico"
|
||||
1095
comtool/qextserialport/qextserialport.cpp
Normal file
1095
comtool/qextserialport/qextserialport.cpp
Normal file
File diff suppressed because it is too large
Load Diff
234
comtool/qextserialport/qextserialport.h
Normal file
234
comtool/qextserialport/qextserialport.h
Normal file
@@ -0,0 +1,234 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _QEXTSERIALPORT_H_
|
||||
#define _QEXTSERIALPORT_H_
|
||||
|
||||
#include <QtCore/QIODevice>
|
||||
#include "qextserialport_global.h"
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <termios.h>
|
||||
#endif
|
||||
/*line status constants*/
|
||||
// ### QESP2.0 move to enum
|
||||
#define LS_CTS 0x01
|
||||
#define LS_DSR 0x02
|
||||
#define LS_DCD 0x04
|
||||
#define LS_RI 0x08
|
||||
#define LS_RTS 0x10
|
||||
#define LS_DTR 0x20
|
||||
#define LS_ST 0x40
|
||||
#define LS_SR 0x80
|
||||
|
||||
/*error constants*/
|
||||
// ### QESP2.0 move to enum
|
||||
#define E_NO_ERROR 0
|
||||
#define E_INVALID_FD 1
|
||||
#define E_NO_MEMORY 2
|
||||
#define E_CAUGHT_NON_BLOCKED_SIGNAL 3
|
||||
#define E_PORT_TIMEOUT 4
|
||||
#define E_INVALID_DEVICE 5
|
||||
#define E_BREAK_CONDITION 6
|
||||
#define E_FRAMING_ERROR 7
|
||||
#define E_IO_ERROR 8
|
||||
#define E_BUFFER_OVERRUN 9
|
||||
#define E_RECEIVE_OVERFLOW 10
|
||||
#define E_RECEIVE_PARITY_ERROR 11
|
||||
#define E_TRANSMIT_OVERFLOW 12
|
||||
#define E_READ_FAILED 13
|
||||
#define E_WRITE_FAILED 14
|
||||
#define E_FILE_NOT_FOUND 15
|
||||
#define E_PERMISSION_DENIED 16
|
||||
#define E_AGAIN 17
|
||||
|
||||
enum BaudRateType {
|
||||
#if defined(Q_OS_UNIX) || defined(qdoc)
|
||||
BAUD50 = 50, //POSIX ONLY
|
||||
BAUD75 = 75, //POSIX ONLY
|
||||
BAUD134 = 134, //POSIX ONLY
|
||||
BAUD150 = 150, //POSIX ONLY
|
||||
BAUD200 = 200, //POSIX ONLY
|
||||
BAUD1800 = 1800, //POSIX ONLY
|
||||
# if defined(B76800) || defined(qdoc)
|
||||
BAUD76800 = 76800, //POSIX ONLY
|
||||
# endif
|
||||
# if (defined(B230400) && defined(B4000000)) || defined(qdoc)
|
||||
BAUD230400 = 230400, //POSIX ONLY
|
||||
BAUD460800 = 460800, //POSIX ONLY
|
||||
BAUD500000 = 500000, //POSIX ONLY
|
||||
BAUD576000 = 576000, //POSIX ONLY
|
||||
BAUD921600 = 921600, //POSIX ONLY
|
||||
BAUD1000000 = 1000000, //POSIX ONLY
|
||||
BAUD1152000 = 1152000, //POSIX ONLY
|
||||
BAUD1500000 = 1500000, //POSIX ONLY
|
||||
BAUD2000000 = 2000000, //POSIX ONLY
|
||||
BAUD2500000 = 2500000, //POSIX ONLY
|
||||
BAUD3000000 = 3000000, //POSIX ONLY
|
||||
BAUD3500000 = 3500000, //POSIX ONLY
|
||||
BAUD4000000 = 4000000, //POSIX ONLY
|
||||
# endif
|
||||
#endif //Q_OS_UNIX
|
||||
#if defined(Q_OS_WIN) || defined(qdoc)
|
||||
BAUD14400 = 14400, //WINDOWS ONLY
|
||||
BAUD56000 = 56000, //WINDOWS ONLY
|
||||
BAUD128000 = 128000, //WINDOWS ONLY
|
||||
BAUD256000 = 256000, //WINDOWS ONLY
|
||||
#endif //Q_OS_WIN
|
||||
BAUD110 = 110,
|
||||
BAUD300 = 300,
|
||||
BAUD600 = 600,
|
||||
BAUD1200 = 1200,
|
||||
BAUD2400 = 2400,
|
||||
BAUD4800 = 4800,
|
||||
BAUD9600 = 9600,
|
||||
BAUD19200 = 19200,
|
||||
BAUD38400 = 38400,
|
||||
BAUD57600 = 57600,
|
||||
BAUD115200 = 115200
|
||||
};
|
||||
|
||||
enum DataBitsType {
|
||||
DATA_5 = 5,
|
||||
DATA_6 = 6,
|
||||
DATA_7 = 7,
|
||||
DATA_8 = 8
|
||||
};
|
||||
|
||||
enum ParityType {
|
||||
PAR_NONE,
|
||||
PAR_ODD,
|
||||
PAR_EVEN,
|
||||
#if defined(Q_OS_WIN) || defined(qdoc)
|
||||
PAR_MARK, //WINDOWS ONLY
|
||||
#endif
|
||||
PAR_SPACE
|
||||
};
|
||||
|
||||
enum StopBitsType {
|
||||
STOP_1,
|
||||
#if defined(Q_OS_WIN) || defined(qdoc)
|
||||
STOP_1_5, //WINDOWS ONLY
|
||||
#endif
|
||||
STOP_2
|
||||
};
|
||||
|
||||
enum FlowType {
|
||||
FLOW_OFF,
|
||||
FLOW_HARDWARE,
|
||||
FLOW_XONXOFF
|
||||
};
|
||||
|
||||
/**
|
||||
* structure to contain port settings
|
||||
*/
|
||||
struct PortSettings {
|
||||
BaudRateType BaudRate;
|
||||
DataBitsType DataBits;
|
||||
ParityType Parity;
|
||||
StopBitsType StopBits;
|
||||
FlowType FlowControl;
|
||||
long Timeout_Millisec;
|
||||
};
|
||||
|
||||
class QextSerialPortPrivate;
|
||||
class QEXTSERIALPORT_EXPORT QextSerialPort: public QIODevice
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(QextSerialPort)
|
||||
Q_ENUMS(QueryMode)
|
||||
Q_PROPERTY(QString portName READ portName WRITE setPortName)
|
||||
Q_PROPERTY(QueryMode queryMode READ queryMode WRITE setQueryMode)
|
||||
public:
|
||||
enum QueryMode {
|
||||
Polling,
|
||||
EventDriven
|
||||
};
|
||||
|
||||
explicit QextSerialPort(QueryMode mode = EventDriven, QObject *parent = 0);
|
||||
explicit QextSerialPort(const QString &name, QueryMode mode = EventDriven, QObject *parent = 0);
|
||||
explicit QextSerialPort(const PortSettings &s, QueryMode mode = EventDriven, QObject *parent = 0);
|
||||
QextSerialPort(const QString &name, const PortSettings &s, QueryMode mode = EventDriven, QObject *parent = 0);
|
||||
|
||||
~QextSerialPort();
|
||||
|
||||
QString portName() const;
|
||||
QueryMode queryMode() const;
|
||||
BaudRateType baudRate() const;
|
||||
DataBitsType dataBits() const;
|
||||
ParityType parity() const;
|
||||
StopBitsType stopBits() const;
|
||||
FlowType flowControl() const;
|
||||
|
||||
bool open(OpenMode mode);
|
||||
bool isSequential() const;
|
||||
void close();
|
||||
void flush();
|
||||
qint64 bytesAvailable() const;
|
||||
bool canReadLine() const;
|
||||
QByteArray readAll();
|
||||
|
||||
ulong lastError() const;
|
||||
|
||||
ulong lineStatus();
|
||||
QString errorString();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setPortName(const QString &name);
|
||||
void setQueryMode(QueryMode mode);
|
||||
void setBaudRate(BaudRateType);
|
||||
void setDataBits(DataBitsType);
|
||||
void setParity(ParityType);
|
||||
void setStopBits(StopBitsType);
|
||||
void setFlowControl(FlowType);
|
||||
void setTimeout(long);
|
||||
|
||||
void setDtr(bool set = true);
|
||||
void setRts(bool set = true);
|
||||
|
||||
Q_SIGNALS:
|
||||
void dsrChanged(bool status);
|
||||
|
||||
protected:
|
||||
qint64 readData(char *data, qint64 maxSize);
|
||||
qint64 writeData(const char *data, qint64 maxSize);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QextSerialPort)
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_onWinEvent(HANDLE))
|
||||
#endif
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_canRead())
|
||||
|
||||
QextSerialPortPrivate *const d_ptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
9
comtool/qextserialport/qextserialport.pri
Normal file
9
comtool/qextserialport/qextserialport.pri
Normal file
@@ -0,0 +1,9 @@
|
||||
HEADERS += \
|
||||
$$PWD/qextserialport.h \
|
||||
$$PWD/qextserialport_global.h \
|
||||
$$PWD/qextserialport_p.h
|
||||
|
||||
SOURCES += $$PWD/qextserialport.cpp
|
||||
|
||||
win32:SOURCES += $$PWD/qextserialport_win.cpp
|
||||
unix:SOURCES += $$PWD/qextserialport_unix.cpp
|
||||
72
comtool/qextserialport/qextserialport_global.h
Normal file
72
comtool/qextserialport/qextserialport_global.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QEXTSERIALPORT_GLOBAL_H
|
||||
#define QEXTSERIALPORT_GLOBAL_H
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#ifdef QEXTSERIALPORT_BUILD_SHARED
|
||||
# define QEXTSERIALPORT_EXPORT Q_DECL_EXPORT
|
||||
#elif defined(QEXTSERIALPORT_USING_SHARED)
|
||||
# define QEXTSERIALPORT_EXPORT Q_DECL_IMPORT
|
||||
#else
|
||||
# define QEXTSERIALPORT_EXPORT
|
||||
#endif
|
||||
|
||||
// ### for compatible with old version. should be removed in QESP 2.0
|
||||
#ifdef _TTY_NOWARN_
|
||||
# define QESP_NO_WARN
|
||||
#endif
|
||||
#ifdef _TTY_NOWARN_PORT_
|
||||
# define QESP_NO_PORTABILITY_WARN
|
||||
#endif
|
||||
|
||||
/*if all warning messages are turned off, flag portability warnings to be turned off as well*/
|
||||
#ifdef QESP_NO_WARN
|
||||
# define QESP_NO_PORTABILITY_WARN
|
||||
#endif
|
||||
|
||||
/*macros for warning and debug messages*/
|
||||
#ifdef QESP_NO_PORTABILITY_WARN
|
||||
# define QESP_PORTABILITY_WARNING while (false)qWarning
|
||||
#else
|
||||
# define QESP_PORTABILITY_WARNING qWarning
|
||||
#endif /*QESP_NOWARN_PORT*/
|
||||
|
||||
#ifdef QESP_NO_WARN
|
||||
# define QESP_WARNING while (false)qWarning
|
||||
#else
|
||||
# define QESP_WARNING qWarning
|
||||
#endif /*QESP_NOWARN*/
|
||||
|
||||
#endif // QEXTSERIALPORT_GLOBAL_H
|
||||
|
||||
277
comtool/qextserialport/qextserialport_p.h
Normal file
277
comtool/qextserialport/qextserialport_p.h
Normal file
@@ -0,0 +1,277 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _QEXTSERIALPORT_P_H_
|
||||
#define _QEXTSERIALPORT_P_H_
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the QESP API. It exists for the convenience
|
||||
// of other QESP classes. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qextserialport.h"
|
||||
#include <QtCore/QReadWriteLock>
|
||||
#ifdef Q_OS_UNIX
|
||||
# include <termios.h>
|
||||
#elif (defined Q_OS_WIN)
|
||||
# include <QtCore/qt_windows.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
// This is QextSerialPort's read buffer, needed by posix system.
|
||||
// ref: QRingBuffer & QIODevicePrivateLinearBuffer
|
||||
class QextReadBuffer
|
||||
{
|
||||
public:
|
||||
inline QextReadBuffer(size_t growth = 4096)
|
||||
: len(0), first(0), buf(0), capacity(0), basicBlockSize(growth)
|
||||
{
|
||||
}
|
||||
|
||||
~QextReadBuffer()
|
||||
{
|
||||
delete buf;
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
first = buf;
|
||||
len = 0;
|
||||
}
|
||||
|
||||
inline int size() const
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
inline bool isEmpty() const
|
||||
{
|
||||
return len == 0;
|
||||
}
|
||||
|
||||
inline int read(char *target, int size)
|
||||
{
|
||||
int r = qMin(size, len);
|
||||
|
||||
if (r == 1) {
|
||||
*target = *first;
|
||||
--len;
|
||||
++first;
|
||||
} else {
|
||||
memcpy(target, first, r);
|
||||
len -= r;
|
||||
first += r;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline char *reserve(size_t size)
|
||||
{
|
||||
if ((first - buf) + len + size > capacity) {
|
||||
size_t newCapacity = qMax(capacity, basicBlockSize);
|
||||
|
||||
while (newCapacity < len + size) {
|
||||
newCapacity *= 2;
|
||||
}
|
||||
|
||||
if (newCapacity > capacity) {
|
||||
// allocate more space
|
||||
char *newBuf = new char[newCapacity];
|
||||
memmove(newBuf, first, len);
|
||||
delete buf;
|
||||
buf = newBuf;
|
||||
capacity = newCapacity;
|
||||
} else {
|
||||
// shift any existing data to make space
|
||||
memmove(buf, first, len);
|
||||
}
|
||||
|
||||
first = buf;
|
||||
}
|
||||
|
||||
char *writePtr = first + len;
|
||||
len += (int)size;
|
||||
return writePtr;
|
||||
}
|
||||
|
||||
inline void chop(int size)
|
||||
{
|
||||
if (size >= len) {
|
||||
clear();
|
||||
} else {
|
||||
len -= size;
|
||||
}
|
||||
}
|
||||
|
||||
inline void squeeze()
|
||||
{
|
||||
if (first != buf) {
|
||||
memmove(buf, first, len);
|
||||
first = buf;
|
||||
}
|
||||
|
||||
size_t newCapacity = basicBlockSize;
|
||||
|
||||
while (newCapacity < size_t(len)) {
|
||||
newCapacity *= 2;
|
||||
}
|
||||
|
||||
if (newCapacity < capacity) {
|
||||
char *tmp = static_cast<char *>(realloc(buf, newCapacity));
|
||||
|
||||
if (tmp) {
|
||||
buf = tmp;
|
||||
capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline QByteArray readAll()
|
||||
{
|
||||
char *f = first;
|
||||
int l = len;
|
||||
clear();
|
||||
return QByteArray(f, l);
|
||||
}
|
||||
|
||||
inline int readLine(char *target, int size)
|
||||
{
|
||||
int r = qMin(size, len);
|
||||
char *eol = static_cast<char *>(memchr(first, '\n', r));
|
||||
|
||||
if (eol) {
|
||||
r = 1 + (eol - first);
|
||||
}
|
||||
|
||||
memcpy(target, first, r);
|
||||
len -= r;
|
||||
first += r;
|
||||
return int(r);
|
||||
}
|
||||
|
||||
inline bool canReadLine() const
|
||||
{
|
||||
return memchr(first, '\n', len);
|
||||
}
|
||||
|
||||
private:
|
||||
int len;
|
||||
char *first;
|
||||
char *buf;
|
||||
size_t capacity;
|
||||
size_t basicBlockSize;
|
||||
};
|
||||
|
||||
class QWinEventNotifier;
|
||||
class QReadWriteLock;
|
||||
class QSocketNotifier;
|
||||
|
||||
class QextSerialPortPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QextSerialPort)
|
||||
public:
|
||||
QextSerialPortPrivate(QextSerialPort *q);
|
||||
~QextSerialPortPrivate();
|
||||
enum DirtyFlagEnum {
|
||||
DFE_BaudRate = 0x0001,
|
||||
DFE_Parity = 0x0002,
|
||||
DFE_StopBits = 0x0004,
|
||||
DFE_DataBits = 0x0008,
|
||||
DFE_Flow = 0x0010,
|
||||
DFE_TimeOut = 0x0100,
|
||||
DFE_ALL = 0x0fff,
|
||||
DFE_Settings_Mask = 0x00ff //without TimeOut
|
||||
};
|
||||
mutable QReadWriteLock lock;
|
||||
QString port;
|
||||
PortSettings settings;
|
||||
QextReadBuffer readBuffer;
|
||||
int settingsDirtyFlags;
|
||||
ulong lastErr;
|
||||
QextSerialPort::QueryMode queryMode;
|
||||
|
||||
// platform specific members
|
||||
#ifdef Q_OS_UNIX
|
||||
int fd;
|
||||
QSocketNotifier *readNotifier;
|
||||
struct termios currentTermios;
|
||||
struct termios oldTermios;
|
||||
#elif (defined Q_OS_WIN)
|
||||
HANDLE handle;
|
||||
OVERLAPPED overlap;
|
||||
COMMCONFIG commConfig;
|
||||
COMMTIMEOUTS commTimeouts;
|
||||
QWinEventNotifier *winEventNotifier;
|
||||
DWORD eventMask;
|
||||
QList<OVERLAPPED *> pendingWrites;
|
||||
QReadWriteLock *bytesToWriteLock;
|
||||
#endif
|
||||
|
||||
/*fill PortSettings*/
|
||||
void setBaudRate(BaudRateType baudRate, bool update = true);
|
||||
void setDataBits(DataBitsType dataBits, bool update = true);
|
||||
void setParity(ParityType parity, bool update = true);
|
||||
void setStopBits(StopBitsType stopbits, bool update = true);
|
||||
void setFlowControl(FlowType flow, bool update = true);
|
||||
void setTimeout(long millisec, bool update = true);
|
||||
void setPortSettings(const PortSettings &settings, bool update = true);
|
||||
|
||||
void platformSpecificDestruct();
|
||||
void platformSpecificInit();
|
||||
void translateError(ulong error);
|
||||
void updatePortSettings();
|
||||
|
||||
qint64 readData_sys(char *data, qint64 maxSize);
|
||||
qint64 writeData_sys(const char *data, qint64 maxSize);
|
||||
void setDtr_sys(bool set = true);
|
||||
void setRts_sys(bool set = true);
|
||||
bool open_sys(QIODevice::OpenMode mode);
|
||||
bool close_sys();
|
||||
bool flush_sys();
|
||||
ulong lineStatus_sys();
|
||||
qint64 bytesAvailable_sys() const;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
void _q_onWinEvent(HANDLE h);
|
||||
#endif
|
||||
void _q_canRead();
|
||||
|
||||
QextSerialPort *q_ptr;
|
||||
};
|
||||
|
||||
#endif //_QEXTSERIALPORT_P_H_
|
||||
559
comtool/qextserialport/qextserialport_unix.cpp
Normal file
559
comtool/qextserialport/qextserialport_unix.cpp
Normal file
@@ -0,0 +1,559 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qextserialport.h"
|
||||
#include "qextserialport_p.h"
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <QtCore/QMutexLocker>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSocketNotifier>
|
||||
|
||||
void QextSerialPortPrivate::platformSpecificInit()
|
||||
{
|
||||
fd = 0;
|
||||
readNotifier = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Standard destructor.
|
||||
*/
|
||||
void QextSerialPortPrivate::platformSpecificDestruct()
|
||||
{
|
||||
}
|
||||
|
||||
static QString fullPortName(const QString &name)
|
||||
{
|
||||
if (name.startsWith(QLatin1Char('/'))) {
|
||||
return name;
|
||||
}
|
||||
|
||||
return QLatin1String("/dev/") + name;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode)
|
||||
{
|
||||
Q_Q(QextSerialPort);
|
||||
|
||||
//note: linux 2.6.21 seems to ignore O_NDELAY flag
|
||||
if ((fd = ::open(fullPortName(port).toLatin1() , O_RDWR | O_NOCTTY | O_NDELAY)) != -1) {
|
||||
|
||||
/*In the Private class, We can not call QIODevice::open()*/
|
||||
q->setOpenMode(mode); // Flag the port as opened
|
||||
::tcgetattr(fd, &oldTermios); // Save the old termios
|
||||
currentTermios = oldTermios; // Make a working copy
|
||||
::cfmakeraw(¤tTermios); // Enable raw access
|
||||
|
||||
/*set up other port settings*/
|
||||
currentTermios.c_cflag |= CREAD | CLOCAL;
|
||||
currentTermios.c_lflag &= (~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG));
|
||||
currentTermios.c_iflag &= (~(INPCK | IGNPAR | PARMRK | ISTRIP | ICRNL | IXANY));
|
||||
currentTermios.c_oflag &= (~OPOST);
|
||||
currentTermios.c_cc[VMIN] = 0;
|
||||
#ifdef _POSIX_VDISABLE // Is a disable character available on this system?
|
||||
// Some systems allow for per-device disable-characters, so get the
|
||||
// proper value for the configured device
|
||||
const long vdisable = ::fpathconf(fd, _PC_VDISABLE);
|
||||
currentTermios.c_cc[VINTR] = vdisable;
|
||||
currentTermios.c_cc[VQUIT] = vdisable;
|
||||
currentTermios.c_cc[VSTART] = vdisable;
|
||||
currentTermios.c_cc[VSTOP] = vdisable;
|
||||
currentTermios.c_cc[VSUSP] = vdisable;
|
||||
#endif //_POSIX_VDISABLE
|
||||
settingsDirtyFlags = DFE_ALL;
|
||||
updatePortSettings();
|
||||
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
readNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q);
|
||||
q->connect(readNotifier, SIGNAL(activated(int)), q, SLOT(_q_canRead()));
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
translateError(errno);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::close_sys()
|
||||
{
|
||||
// Force a flush and then restore the original termios
|
||||
flush_sys();
|
||||
// Using both TCSAFLUSH and TCSANOW here discards any pending input
|
||||
::tcsetattr(fd, TCSAFLUSH | TCSANOW, &oldTermios); // Restore termios
|
||||
::close(fd);
|
||||
|
||||
if (readNotifier) {
|
||||
delete readNotifier;
|
||||
readNotifier = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::flush_sys()
|
||||
{
|
||||
::tcdrain(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
qint64 QextSerialPortPrivate::bytesAvailable_sys() const
|
||||
{
|
||||
int bytesQueued;
|
||||
|
||||
if (::ioctl(fd, FIONREAD, &bytesQueued) == -1) {
|
||||
return (qint64) - 1;
|
||||
}
|
||||
|
||||
return bytesQueued;
|
||||
}
|
||||
|
||||
/*!
|
||||
Translates a system-specific error code to a QextSerialPort error code. Used internally.
|
||||
*/
|
||||
void QextSerialPortPrivate::translateError(ulong error)
|
||||
{
|
||||
switch (error) {
|
||||
case EBADF:
|
||||
case ENOTTY:
|
||||
lastErr = E_INVALID_FD;
|
||||
break;
|
||||
|
||||
case EINTR:
|
||||
lastErr = E_CAUGHT_NON_BLOCKED_SIGNAL;
|
||||
break;
|
||||
|
||||
case ENOMEM:
|
||||
lastErr = E_NO_MEMORY;
|
||||
break;
|
||||
|
||||
case EACCES:
|
||||
lastErr = E_PERMISSION_DENIED;
|
||||
break;
|
||||
|
||||
case EAGAIN:
|
||||
lastErr = E_AGAIN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::setDtr_sys(bool set)
|
||||
{
|
||||
int status;
|
||||
::ioctl(fd, TIOCMGET, &status);
|
||||
|
||||
if (set) {
|
||||
status |= TIOCM_DTR;
|
||||
} else {
|
||||
status &= ~TIOCM_DTR;
|
||||
}
|
||||
|
||||
::ioctl(fd, TIOCMSET, &status);
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::setRts_sys(bool set)
|
||||
{
|
||||
int status;
|
||||
::ioctl(fd, TIOCMGET, &status);
|
||||
|
||||
if (set) {
|
||||
status |= TIOCM_RTS;
|
||||
} else {
|
||||
status &= ~TIOCM_RTS;
|
||||
}
|
||||
|
||||
::ioctl(fd, TIOCMSET, &status);
|
||||
}
|
||||
|
||||
unsigned long QextSerialPortPrivate::lineStatus_sys()
|
||||
{
|
||||
unsigned long Status = 0, Temp = 0;
|
||||
::ioctl(fd, TIOCMGET, &Temp);
|
||||
|
||||
if (Temp & TIOCM_CTS) {
|
||||
Status |= LS_CTS;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_DSR) {
|
||||
Status |= LS_DSR;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_RI) {
|
||||
Status |= LS_RI;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_CD) {
|
||||
Status |= LS_DCD;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_DTR) {
|
||||
Status |= LS_DTR;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_RTS) {
|
||||
Status |= LS_RTS;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_ST) {
|
||||
Status |= LS_ST;
|
||||
}
|
||||
|
||||
if (Temp & TIOCM_SR) {
|
||||
Status |= LS_SR;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*!
|
||||
Reads a block of data from the serial port. This function will read at most maxSize bytes from
|
||||
the serial port and place them in the buffer pointed to by data. Return value is the number of
|
||||
bytes actually read, or -1 on error.
|
||||
|
||||
\warning before calling this function ensure that serial port associated with this class
|
||||
is currently open (use isOpen() function to check if port is open).
|
||||
*/
|
||||
qint64 QextSerialPortPrivate::readData_sys(char *data, qint64 maxSize)
|
||||
{
|
||||
int retVal = ::read(fd, data, maxSize);
|
||||
|
||||
if (retVal == -1) {
|
||||
lastErr = E_READ_FAILED;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*!
|
||||
Writes a block of data to the serial port. This function will write maxSize bytes
|
||||
from the buffer pointed to by data to the serial port. Return value is the number
|
||||
of bytes actually written, or -1 on error.
|
||||
|
||||
\warning before calling this function ensure that serial port associated with this class
|
||||
is currently open (use isOpen() function to check if port is open).
|
||||
*/
|
||||
qint64 QextSerialPortPrivate::writeData_sys(const char *data, qint64 maxSize)
|
||||
{
|
||||
int retVal = ::write(fd, data, maxSize);
|
||||
|
||||
if (retVal == -1) {
|
||||
lastErr = E_WRITE_FAILED;
|
||||
}
|
||||
|
||||
return (qint64)retVal;
|
||||
}
|
||||
|
||||
static void setBaudRate2Termios(termios *config, int baudRate)
|
||||
{
|
||||
#ifdef CBAUD
|
||||
config->c_cflag &= (~CBAUD);
|
||||
config->c_cflag |= baudRate;
|
||||
#else
|
||||
::cfsetispeed(config, baudRate);
|
||||
::cfsetospeed(config, baudRate);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
All the platform settings was performed in this function.
|
||||
*/
|
||||
void QextSerialPortPrivate::updatePortSettings()
|
||||
{
|
||||
if (!q_func()->isOpen() || !settingsDirtyFlags) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_BaudRate) {
|
||||
switch (settings.BaudRate) {
|
||||
case BAUD50:
|
||||
setBaudRate2Termios(¤tTermios, B50);
|
||||
break;
|
||||
|
||||
case BAUD75:
|
||||
setBaudRate2Termios(¤tTermios, B75);
|
||||
break;
|
||||
|
||||
case BAUD110:
|
||||
setBaudRate2Termios(¤tTermios, B110);
|
||||
break;
|
||||
|
||||
case BAUD134:
|
||||
setBaudRate2Termios(¤tTermios, B134);
|
||||
break;
|
||||
|
||||
case BAUD150:
|
||||
setBaudRate2Termios(¤tTermios, B150);
|
||||
break;
|
||||
|
||||
case BAUD200:
|
||||
setBaudRate2Termios(¤tTermios, B200);
|
||||
break;
|
||||
|
||||
case BAUD300:
|
||||
setBaudRate2Termios(¤tTermios, B300);
|
||||
break;
|
||||
|
||||
case BAUD600:
|
||||
setBaudRate2Termios(¤tTermios, B600);
|
||||
break;
|
||||
|
||||
case BAUD1200:
|
||||
setBaudRate2Termios(¤tTermios, B1200);
|
||||
break;
|
||||
|
||||
case BAUD1800:
|
||||
setBaudRate2Termios(¤tTermios, B1800);
|
||||
break;
|
||||
|
||||
case BAUD2400:
|
||||
setBaudRate2Termios(¤tTermios, B2400);
|
||||
break;
|
||||
|
||||
case BAUD4800:
|
||||
setBaudRate2Termios(¤tTermios, B4800);
|
||||
break;
|
||||
|
||||
case BAUD9600:
|
||||
setBaudRate2Termios(¤tTermios, B9600);
|
||||
break;
|
||||
|
||||
case BAUD19200:
|
||||
setBaudRate2Termios(¤tTermios, B19200);
|
||||
break;
|
||||
|
||||
case BAUD38400:
|
||||
setBaudRate2Termios(¤tTermios, B38400);
|
||||
break;
|
||||
|
||||
case BAUD57600:
|
||||
setBaudRate2Termios(¤tTermios, B57600);
|
||||
break;
|
||||
#ifdef B76800
|
||||
|
||||
case BAUD76800:
|
||||
setBaudRate2Termios(¤tTermios, B76800);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case BAUD115200:
|
||||
setBaudRate2Termios(¤tTermios, B115200);
|
||||
break;
|
||||
#if defined(B230400) && defined(B4000000)
|
||||
|
||||
case BAUD230400:
|
||||
setBaudRate2Termios(¤tTermios, B230400);
|
||||
break;
|
||||
|
||||
case BAUD460800:
|
||||
setBaudRate2Termios(¤tTermios, B460800);
|
||||
break;
|
||||
|
||||
case BAUD500000:
|
||||
setBaudRate2Termios(¤tTermios, B500000);
|
||||
break;
|
||||
|
||||
case BAUD576000:
|
||||
setBaudRate2Termios(¤tTermios, B576000);
|
||||
break;
|
||||
|
||||
case BAUD921600:
|
||||
setBaudRate2Termios(¤tTermios, B921600);
|
||||
break;
|
||||
|
||||
case BAUD1000000:
|
||||
setBaudRate2Termios(¤tTermios, B1000000);
|
||||
break;
|
||||
|
||||
case BAUD1152000:
|
||||
setBaudRate2Termios(¤tTermios, B1152000);
|
||||
break;
|
||||
|
||||
case BAUD1500000:
|
||||
setBaudRate2Termios(¤tTermios, B1500000);
|
||||
break;
|
||||
|
||||
case BAUD2000000:
|
||||
setBaudRate2Termios(¤tTermios, B2000000);
|
||||
break;
|
||||
|
||||
case BAUD2500000:
|
||||
setBaudRate2Termios(¤tTermios, B2500000);
|
||||
break;
|
||||
|
||||
case BAUD3000000:
|
||||
setBaudRate2Termios(¤tTermios, B3000000);
|
||||
break;
|
||||
|
||||
case BAUD3500000:
|
||||
setBaudRate2Termios(¤tTermios, B3500000);
|
||||
break;
|
||||
|
||||
case BAUD4000000:
|
||||
setBaudRate2Termios(¤tTermios, B4000000);
|
||||
break;
|
||||
#endif
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
default:
|
||||
setBaudRate2Termios(¤tTermios, settings.BaudRate);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_Parity) {
|
||||
switch (settings.Parity) {
|
||||
case PAR_SPACE:
|
||||
/*space parity not directly supported - add an extra data bit to simulate it*/
|
||||
settingsDirtyFlags |= DFE_DataBits;
|
||||
break;
|
||||
|
||||
case PAR_NONE:
|
||||
currentTermios.c_cflag &= (~PARENB);
|
||||
break;
|
||||
|
||||
case PAR_EVEN:
|
||||
currentTermios.c_cflag &= (~PARODD);
|
||||
currentTermios.c_cflag |= PARENB;
|
||||
break;
|
||||
|
||||
case PAR_ODD:
|
||||
currentTermios.c_cflag |= (PARENB | PARODD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*must after Parity settings*/
|
||||
if (settingsDirtyFlags & DFE_DataBits) {
|
||||
if (settings.Parity != PAR_SPACE) {
|
||||
currentTermios.c_cflag &= (~CSIZE);
|
||||
|
||||
switch (settings.DataBits) {
|
||||
case DATA_5:
|
||||
currentTermios.c_cflag |= CS5;
|
||||
break;
|
||||
|
||||
case DATA_6:
|
||||
currentTermios.c_cflag |= CS6;
|
||||
break;
|
||||
|
||||
case DATA_7:
|
||||
currentTermios.c_cflag |= CS7;
|
||||
break;
|
||||
|
||||
case DATA_8:
|
||||
currentTermios.c_cflag |= CS8;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/*space parity not directly supported - add an extra data bit to simulate it*/
|
||||
currentTermios.c_cflag &= ~(PARENB | CSIZE);
|
||||
|
||||
switch (settings.DataBits) {
|
||||
case DATA_5:
|
||||
currentTermios.c_cflag |= CS6;
|
||||
break;
|
||||
|
||||
case DATA_6:
|
||||
currentTermios.c_cflag |= CS7;
|
||||
break;
|
||||
|
||||
case DATA_7:
|
||||
currentTermios.c_cflag |= CS8;
|
||||
break;
|
||||
|
||||
case DATA_8:
|
||||
/*this will never happen, put here to Suppress an warning*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_StopBits) {
|
||||
switch (settings.StopBits) {
|
||||
case STOP_1:
|
||||
currentTermios.c_cflag &= (~CSTOPB);
|
||||
break;
|
||||
|
||||
case STOP_2:
|
||||
currentTermios.c_cflag |= CSTOPB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_Flow) {
|
||||
switch (settings.FlowControl) {
|
||||
case FLOW_OFF:
|
||||
currentTermios.c_cflag &= (~CRTSCTS);
|
||||
currentTermios.c_iflag &= (~(IXON | IXOFF | IXANY));
|
||||
break;
|
||||
|
||||
case FLOW_XONXOFF:
|
||||
/*software (XON/XOFF) flow control*/
|
||||
currentTermios.c_cflag &= (~CRTSCTS);
|
||||
currentTermios.c_iflag |= (IXON | IXOFF | IXANY);
|
||||
break;
|
||||
|
||||
case FLOW_HARDWARE:
|
||||
currentTermios.c_cflag |= CRTSCTS;
|
||||
currentTermios.c_iflag &= (~(IXON | IXOFF | IXANY));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*if any thing in currentTermios changed, flush*/
|
||||
if (settingsDirtyFlags & DFE_Settings_Mask) {
|
||||
::tcsetattr(fd, TCSAFLUSH, ¤tTermios);
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_TimeOut) {
|
||||
int millisec = settings.Timeout_Millisec;
|
||||
|
||||
if (millisec == -1) {
|
||||
::fcntl(fd, F_SETFL, O_NDELAY);
|
||||
} else {
|
||||
//O_SYNC should enable blocking ::write()
|
||||
//however this seems not working on Linux 2.6.21 (works on OpenBSD 4.2)
|
||||
::fcntl(fd, F_SETFL, O_SYNC);
|
||||
}
|
||||
|
||||
::tcgetattr(fd, ¤tTermios);
|
||||
currentTermios.c_cc[VTIME] = millisec / 100;
|
||||
::tcsetattr(fd, TCSAFLUSH, ¤tTermios);
|
||||
}
|
||||
|
||||
settingsDirtyFlags = 0;
|
||||
}
|
||||
476
comtool/qextserialport/qextserialport_win.cpp
Normal file
476
comtool/qextserialport/qextserialport_win.cpp
Normal file
@@ -0,0 +1,476 @@
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2000-2003 Wayne Roth
|
||||
** Copyright (c) 2004-2007 Stefan Sander
|
||||
** Copyright (c) 2007 Michal Policht
|
||||
** Copyright (c) 2008 Brandon Fosdick
|
||||
** Copyright (c) 2009-2010 Liam Staskawicz
|
||||
** Copyright (c) 2011 Debao Zhang
|
||||
** All right reserved.
|
||||
** Web: http://code.google.com/p/qextserialport/
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining
|
||||
** a copy of this software and associated documentation files (the
|
||||
** "Software"), to deal in the Software without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Software, and to
|
||||
** permit persons to whom the Software is furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be
|
||||
** included in all copies or substantial portions of the Software.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qextserialport.h"
|
||||
#include "qextserialport_p.h"
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QReadWriteLock>
|
||||
#include <QtCore/QMutexLocker>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtCore/QMetaType>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
# include <QtCore/QWinEventNotifier>
|
||||
#else
|
||||
# include <QtCore/private/qwineventnotifier_p.h>
|
||||
#endif
|
||||
void QextSerialPortPrivate::platformSpecificInit()
|
||||
{
|
||||
handle = INVALID_HANDLE_VALUE;
|
||||
ZeroMemory(&overlap, sizeof(OVERLAPPED));
|
||||
overlap.hEvent = CreateEvent(NULL, true, false, NULL);
|
||||
winEventNotifier = 0;
|
||||
bytesToWriteLock = new QReadWriteLock;
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::platformSpecificDestruct()
|
||||
{
|
||||
CloseHandle(overlap.hEvent);
|
||||
delete bytesToWriteLock;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\internal
|
||||
COM ports greater than 9 need \\.\ prepended
|
||||
|
||||
This is only need when open the port.
|
||||
*/
|
||||
static QString fullPortNameWin(const QString &name)
|
||||
{
|
||||
QRegExp rx(QLatin1String("^COM(\\d+)"));
|
||||
QString fullName(name);
|
||||
|
||||
if (fullName.contains(rx)) {
|
||||
fullName.prepend(QLatin1String("\\\\.\\"));
|
||||
}
|
||||
|
||||
return fullName;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::open_sys(QIODevice::OpenMode mode)
|
||||
{
|
||||
Q_Q(QextSerialPort);
|
||||
DWORD confSize = sizeof(COMMCONFIG);
|
||||
commConfig.dwSize = confSize;
|
||||
DWORD dwFlagsAndAttributes = 0;
|
||||
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;
|
||||
}
|
||||
|
||||
/*open the port*/
|
||||
handle = CreateFileW((wchar_t *)fullPortNameWin(port).utf16(), GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
q->setOpenMode(mode);
|
||||
/*configure port settings*/
|
||||
GetCommConfig(handle, &commConfig, &confSize);
|
||||
GetCommState(handle, &(commConfig.dcb));
|
||||
|
||||
/*set up parameters*/
|
||||
commConfig.dcb.fBinary = TRUE;
|
||||
commConfig.dcb.fInX = FALSE;
|
||||
commConfig.dcb.fOutX = FALSE;
|
||||
commConfig.dcb.fAbortOnError = FALSE;
|
||||
commConfig.dcb.fNull = FALSE;
|
||||
/* Dtr default to true. See Issue 122*/
|
||||
commConfig.dcb.fDtrControl = TRUE;
|
||||
/*flush all settings*/
|
||||
settingsDirtyFlags = DFE_ALL;
|
||||
updatePortSettings();
|
||||
|
||||
//init event driven approach
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
if (!SetCommMask(handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) {
|
||||
QESP_WARNING() << "failed to set Comm Mask. Error code:" << GetLastError();
|
||||
return false;
|
||||
}
|
||||
|
||||
winEventNotifier = new QWinEventNotifier(overlap.hEvent, q);
|
||||
qRegisterMetaType<HANDLE>("HANDLE");
|
||||
q->connect(winEventNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_onWinEvent(HANDLE)), Qt::DirectConnection);
|
||||
WaitCommEvent(handle, &eventMask, &overlap);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::close_sys()
|
||||
{
|
||||
flush_sys();
|
||||
CancelIo(handle);
|
||||
|
||||
if (CloseHandle(handle)) {
|
||||
handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (winEventNotifier) {
|
||||
winEventNotifier->setEnabled(false);
|
||||
winEventNotifier->deleteLater();
|
||||
winEventNotifier = 0;
|
||||
}
|
||||
|
||||
foreach (OVERLAPPED *o, pendingWrites) {
|
||||
CloseHandle(o->hEvent);
|
||||
delete o;
|
||||
}
|
||||
|
||||
pendingWrites.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QextSerialPortPrivate::flush_sys()
|
||||
{
|
||||
FlushFileBuffers(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
qint64 QextSerialPortPrivate::bytesAvailable_sys() const
|
||||
{
|
||||
DWORD Errors;
|
||||
COMSTAT Status;
|
||||
|
||||
if (ClearCommError(handle, &Errors, &Status)) {
|
||||
return Status.cbInQue;
|
||||
}
|
||||
|
||||
return (qint64) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Translates a system-specific error code to a QextSerialPort error code. Used internally.
|
||||
*/
|
||||
void QextSerialPortPrivate::translateError(ulong error)
|
||||
{
|
||||
if (error & CE_BREAK) {
|
||||
lastErr = E_BREAK_CONDITION;
|
||||
} else if (error & CE_FRAME) {
|
||||
lastErr = E_FRAMING_ERROR;
|
||||
} else if (error & CE_IOE) {
|
||||
lastErr = E_IO_ERROR;
|
||||
} else if (error & CE_MODE) {
|
||||
lastErr = E_INVALID_FD;
|
||||
} else if (error & CE_OVERRUN) {
|
||||
lastErr = E_BUFFER_OVERRUN;
|
||||
} else if (error & CE_RXPARITY) {
|
||||
lastErr = E_RECEIVE_PARITY_ERROR;
|
||||
} else if (error & CE_RXOVER) {
|
||||
lastErr = E_RECEIVE_OVERFLOW;
|
||||
} else if (error & CE_TXFULL) {
|
||||
lastErr = E_TRANSMIT_OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Reads a block of data from the serial port. This function will read at most maxlen bytes from
|
||||
the serial port and place them in the buffer pointed to by data. Return value is the number of
|
||||
bytes actually read, or -1 on error.
|
||||
|
||||
\warning before calling this function ensure that serial port associated with this class
|
||||
is currently open (use isOpen() function to check if port is open).
|
||||
*/
|
||||
qint64 QextSerialPortPrivate::readData_sys(char *data, qint64 maxSize)
|
||||
{
|
||||
DWORD bytesRead = 0;
|
||||
bool failed = false;
|
||||
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
OVERLAPPED overlapRead;
|
||||
ZeroMemory(&overlapRead, sizeof(OVERLAPPED));
|
||||
|
||||
if (!ReadFile(handle, (void *)data, (DWORD)maxSize, &bytesRead, &overlapRead)) {
|
||||
if (GetLastError() == ERROR_IO_PENDING) {
|
||||
GetOverlappedResult(handle, &overlapRead, &bytesRead, true);
|
||||
} else {
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
} else if (!ReadFile(handle, (void *)data, (DWORD)maxSize, &bytesRead, NULL)) {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
return (qint64)bytesRead;
|
||||
}
|
||||
|
||||
lastErr = E_READ_FAILED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
Writes a block of data to the serial port. This function will write len bytes
|
||||
from the buffer pointed to by data to the serial port. Return value is the number
|
||||
of bytes actually written, or -1 on error.
|
||||
|
||||
\warning before calling this function ensure that serial port associated with this class
|
||||
is currently open (use isOpen() function to check if port is open).
|
||||
*/
|
||||
qint64 QextSerialPortPrivate::writeData_sys(const char *data, qint64 maxSize)
|
||||
{
|
||||
DWORD bytesWritten = 0;
|
||||
bool failed = false;
|
||||
|
||||
if (queryMode == QextSerialPort::EventDriven) {
|
||||
OVERLAPPED *newOverlapWrite = new OVERLAPPED;
|
||||
ZeroMemory(newOverlapWrite, sizeof(OVERLAPPED));
|
||||
newOverlapWrite->hEvent = CreateEvent(NULL, true, false, NULL);
|
||||
|
||||
if (WriteFile(handle, (void *)data, (DWORD)maxSize, &bytesWritten, newOverlapWrite)) {
|
||||
CloseHandle(newOverlapWrite->hEvent);
|
||||
delete newOverlapWrite;
|
||||
} else if (GetLastError() == ERROR_IO_PENDING) {
|
||||
// writing asynchronously...not an error
|
||||
QWriteLocker writelocker(bytesToWriteLock);
|
||||
pendingWrites.append(newOverlapWrite);
|
||||
} else {
|
||||
QESP_WARNING() << "QextSerialPort write error:" << GetLastError();
|
||||
failed = true;
|
||||
|
||||
if (!CancelIo(newOverlapWrite->hEvent)) {
|
||||
QESP_WARNING("QextSerialPort: couldn't cancel IO");
|
||||
}
|
||||
|
||||
if (!CloseHandle(newOverlapWrite->hEvent)) {
|
||||
QESP_WARNING("QextSerialPort: couldn't close OVERLAPPED handle");
|
||||
}
|
||||
|
||||
delete newOverlapWrite;
|
||||
}
|
||||
} else if (!WriteFile(handle, (void *)data, (DWORD)maxSize, &bytesWritten, NULL)) {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
return (qint64)bytesWritten;
|
||||
}
|
||||
|
||||
lastErr = E_WRITE_FAILED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::setDtr_sys(bool set)
|
||||
{
|
||||
EscapeCommFunction(handle, set ? SETDTR : CLRDTR);
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::setRts_sys(bool set)
|
||||
{
|
||||
EscapeCommFunction(handle, set ? SETRTS : CLRRTS);
|
||||
}
|
||||
|
||||
ulong QextSerialPortPrivate::lineStatus_sys(void)
|
||||
{
|
||||
unsigned long Status = 0, Temp = 0;
|
||||
GetCommModemStatus(handle, &Temp);
|
||||
|
||||
if (Temp & MS_CTS_ON) {
|
||||
Status |= LS_CTS;
|
||||
}
|
||||
|
||||
if (Temp & MS_DSR_ON) {
|
||||
Status |= LS_DSR;
|
||||
}
|
||||
|
||||
if (Temp & MS_RING_ON) {
|
||||
Status |= LS_RI;
|
||||
}
|
||||
|
||||
if (Temp & MS_RLSD_ON) {
|
||||
Status |= LS_DCD;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
Triggered when there's activity on our HANDLE.
|
||||
*/
|
||||
void QextSerialPortPrivate::_q_onWinEvent(HANDLE h)
|
||||
{
|
||||
Q_Q(QextSerialPort);
|
||||
|
||||
if (h == overlap.hEvent) {
|
||||
if (eventMask & EV_RXCHAR) {
|
||||
if (q->sender() != q && bytesAvailable_sys() > 0) {
|
||||
_q_canRead();
|
||||
}
|
||||
}
|
||||
|
||||
if (eventMask & EV_TXEMPTY) {
|
||||
/*
|
||||
A write completed. Run through the list of OVERLAPPED writes, and if
|
||||
they completed successfully, take them off the list and delete them.
|
||||
Otherwise, leave them on there so they can finish.
|
||||
*/
|
||||
qint64 totalBytesWritten = 0;
|
||||
QList<OVERLAPPED *> overlapsToDelete;
|
||||
|
||||
foreach (OVERLAPPED *o, pendingWrites) {
|
||||
DWORD numBytes = 0;
|
||||
|
||||
if (GetOverlappedResult(handle, o, &numBytes, false)) {
|
||||
overlapsToDelete.append(o);
|
||||
totalBytesWritten += numBytes;
|
||||
} else if (GetLastError() != ERROR_IO_INCOMPLETE) {
|
||||
overlapsToDelete.append(o);
|
||||
QESP_WARNING() << "CommEvent overlapped write error:" << GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
if (q->sender() != q && totalBytesWritten > 0) {
|
||||
QWriteLocker writelocker(bytesToWriteLock);
|
||||
Q_EMIT q->bytesWritten(totalBytesWritten);
|
||||
}
|
||||
|
||||
foreach (OVERLAPPED *o, overlapsToDelete) {
|
||||
OVERLAPPED *toDelete = pendingWrites.takeAt(pendingWrites.indexOf(o));
|
||||
CloseHandle(toDelete->hEvent);
|
||||
delete toDelete;
|
||||
}
|
||||
}
|
||||
|
||||
if (eventMask & EV_DSR) {
|
||||
if (lineStatus_sys() & LS_DSR) {
|
||||
Q_EMIT q->dsrChanged(true);
|
||||
} else {
|
||||
Q_EMIT q->dsrChanged(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WaitCommEvent(handle, &eventMask, &overlap);
|
||||
}
|
||||
|
||||
void QextSerialPortPrivate::updatePortSettings()
|
||||
{
|
||||
if (!q_ptr->isOpen() || !settingsDirtyFlags) {
|
||||
return;
|
||||
}
|
||||
|
||||
//fill struct : COMMCONFIG
|
||||
if (settingsDirtyFlags & DFE_BaudRate) {
|
||||
commConfig.dcb.BaudRate = settings.BaudRate;
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_Parity) {
|
||||
commConfig.dcb.Parity = (BYTE)settings.Parity;
|
||||
commConfig.dcb.fParity = (settings.Parity == PAR_NONE) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_DataBits) {
|
||||
commConfig.dcb.ByteSize = (BYTE)settings.DataBits;
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_StopBits) {
|
||||
switch (settings.StopBits) {
|
||||
case STOP_1:
|
||||
commConfig.dcb.StopBits = ONESTOPBIT;
|
||||
break;
|
||||
|
||||
case STOP_1_5:
|
||||
commConfig.dcb.StopBits = ONE5STOPBITS;
|
||||
break;
|
||||
|
||||
case STOP_2:
|
||||
commConfig.dcb.StopBits = TWOSTOPBITS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (settingsDirtyFlags & DFE_Flow) {
|
||||
switch (settings.FlowControl) {
|
||||
/*no flow control*/
|
||||
case FLOW_OFF:
|
||||
commConfig.dcb.fOutxCtsFlow = FALSE;
|
||||
commConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
commConfig.dcb.fInX = FALSE;
|
||||
commConfig.dcb.fOutX = FALSE;
|
||||
break;
|
||||
|
||||
/*software (XON/XOFF) flow control*/
|
||||
case FLOW_XONXOFF:
|
||||
commConfig.dcb.fOutxCtsFlow = FALSE;
|
||||
commConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
commConfig.dcb.fInX = TRUE;
|
||||
commConfig.dcb.fOutX = TRUE;
|
||||
break;
|
||||
|
||||
/*hardware flow control*/
|
||||
case FLOW_HARDWARE:
|
||||
commConfig.dcb.fOutxCtsFlow = TRUE;
|
||||
commConfig.dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
||||
commConfig.dcb.fInX = FALSE;
|
||||
commConfig.dcb.fOutX = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//fill struct : COMMTIMEOUTS
|
||||
if (settingsDirtyFlags & DFE_TimeOut) {
|
||||
if (queryMode != QextSerialPort::EventDriven) {
|
||||
int millisec = settings.Timeout_Millisec;
|
||||
|
||||
if (millisec == -1) {
|
||||
commTimeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
commTimeouts.ReadTotalTimeoutConstant = 0;
|
||||
} else {
|
||||
commTimeouts.ReadIntervalTimeout = millisec;
|
||||
commTimeouts.ReadTotalTimeoutConstant = millisec;
|
||||
}
|
||||
|
||||
commTimeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
commTimeouts.WriteTotalTimeoutMultiplier = millisec;
|
||||
commTimeouts.WriteTotalTimeoutConstant = 0;
|
||||
} else {
|
||||
commTimeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
commTimeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
commTimeouts.ReadTotalTimeoutConstant = 0;
|
||||
commTimeouts.WriteTotalTimeoutMultiplier = 0;
|
||||
commTimeouts.WriteTotalTimeoutConstant = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (settingsDirtyFlags & DFE_Settings_Mask) {
|
||||
SetCommConfig(handle, &commConfig, sizeof(COMMCONFIG));
|
||||
}
|
||||
|
||||
if ((settingsDirtyFlags & DFE_TimeOut)) {
|
||||
SetCommTimeouts(handle, &commTimeouts);
|
||||
}
|
||||
|
||||
settingsDirtyFlags = 0;
|
||||
}
|
||||
16
comtool/qextserialport/readme.txt
Normal file
16
comtool/qextserialport/readme.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
ʹ<EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
pro<EFBFBD>ļ<EFBFBD>
|
||||
include(qextserialport/qextserialport.pri)
|
||||
|
||||
QextSerialPort *GSM_COM = new QextSerialPort(portName, QextSerialPort::EventDriven);
|
||||
isOpen = GSM_COM->open(QIODevice::ReadWrite);
|
||||
if (isOpen) {
|
||||
GSM_COM->flush();
|
||||
GSM_COM->setBaudRate(BAUD9600);
|
||||
GSM_COM->setDataBits(DATA_8);
|
||||
GSM_COM->setParity(PAR_NONE);
|
||||
GSM_COM->setStopBits(STOP_1);
|
||||
GSM_COM->setFlowControl(FLOW_OFF);
|
||||
GSM_COM->setTimeout(10);
|
||||
}
|
||||
|
||||
16
comtool/readme.txt
Normal file
16
comtool/readme.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD>
|
||||
1<EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD>16<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ա<EFBFBD>
|
||||
2<EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD>windows<EFBFBD><EFBFBD>COM9<EFBFBD><EFBFBD><EFBFBD>ϵĴ<EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD>š<EFBFBD>
|
||||
3<EFBFBD><EFBFBD>ʵʱ<EFBFBD><EFBFBD>ʾ<EFBFBD>շ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڴ<EFBFBD>С<EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD>
|
||||
4<EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>qt<EFBFBD>汾<EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD>4.7.0 4.8.5 4.8.7 5.4.1 5.7.0 5.8.0<EFBFBD><EFBFBD>
|
||||
5<EFBFBD><EFBFBD>֧<EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD>
|
||||
1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>ÿ<EFBFBD><EFBFBD>ֻҪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><EFBFBD>ɣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD>
|
||||
2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD>ظ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>濪<EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD>ظ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>úõ<EFBFBD>ָ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>õĻظ<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>0x16 0x00 0xFF 0x01<30><31>Ҫ<EFBFBD>ظ<EFBFBD>0x16 0x00 0xFE 0x01<30><31><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>Ҫ<EFBFBD><D2AA>SendData.txt<78><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>16 00 FF 01:16 00 FE 01<30><31><EFBFBD>ɡ<EFBFBD>
|
||||
3<EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݺͱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD>ļ<EFBFBD>:<3A><>Ĭ<EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD>5<EFBFBD><35><EFBFBD>ӣ<EFBFBD><D3A3>ɸ<EFBFBD><C9B8>ļ<EFBFBD><C4BC><EFBFBD>ʱ<EFBFBD>䡣
|
||||
4<EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD>Ͻ<EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鿴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD>̨<EFBFBD><EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>رմ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鿴<EFBFBD>ѽ<EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݡ<EFBFBD>
|
||||
5<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѽڵģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
6<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>洦<EFBFBD><EFBFBD><EFBFBD>룬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD>࣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>XP/WIN7/UBUNTU/ARMLINUXϵͳ<CFB5>³ɹ<C2B3><C9B9><EFBFBD><EFBFBD>벢<EFBFBD><EBB2A2><EFBFBD>С<EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>и<EFBFBD><EFBFBD>õĽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Q<EFBFBD><EFBFBD>(517216493)<29><>лл<D0BB><D0BB>
|
||||
20
countcode/countcode.pro
Normal file
20
countcode/countcode.pro
Normal file
@@ -0,0 +1,20 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2017-02-08T09:21:04
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = countcode
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmcountcode.cpp
|
||||
HEADERS += frmcountcode.h
|
||||
FORMS += frmcountcode.ui
|
||||
|
||||
278
countcode/frmcountcode.cpp
Normal file
278
countcode/frmcountcode.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmcountcode.h"
|
||||
#include "ui_frmcountcode.h"
|
||||
#include "qfile.h"
|
||||
#include "qtextstream.h"
|
||||
#include "qfiledialog.h"
|
||||
#include "qfileinfo.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
frmCountCode::frmCountCode(QWidget *parent) : QWidget(parent), ui(new Ui::frmCountCode)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
on_btnClear_clicked();
|
||||
}
|
||||
|
||||
frmCountCode::~frmCountCode()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmCountCode::initForm()
|
||||
{
|
||||
QStringList headText;
|
||||
headText << "文件名" << "类型" << "大小" << "总行数" << "代码行数" << "注释行数" << "空白行数" << "路径";
|
||||
QList<int> columnWidth;
|
||||
columnWidth << 130 << 50 << 70 << 80 << 70 << 70 << 70 << 150;
|
||||
|
||||
int columnCount = headText.count();
|
||||
ui->tableWidget->setColumnCount(columnCount);
|
||||
ui->tableWidget->setHorizontalHeaderLabels(headText);
|
||||
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
ui->tableWidget->verticalHeader()->setVisible(false);
|
||||
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
|
||||
ui->tableWidget->horizontalHeader()->setHighlightSections(false);
|
||||
ui->tableWidget->verticalHeader()->setDefaultSectionSize(20);
|
||||
ui->tableWidget->verticalHeader()->setHighlightSections(false);
|
||||
|
||||
for (int i = 0; i < columnCount; i++) {
|
||||
ui->tableWidget->setColumnWidth(i, columnWidth.at(i));
|
||||
}
|
||||
|
||||
//设置前景色
|
||||
ui->txtCount->setStyleSheet("color:#17A086;");
|
||||
ui->txtSize->setStyleSheet("color:#CA5AA6;");
|
||||
ui->txtRow->setStyleSheet("color:#CD1B19;");
|
||||
ui->txtCode->setStyleSheet("color:#22A3A9;");
|
||||
ui->txtNote->setStyleSheet("color:#D64D54;");
|
||||
ui->txtBlank->setStyleSheet("color:#A279C5;");
|
||||
|
||||
//设置字体加粗
|
||||
QFont font;
|
||||
font.setBold(true);
|
||||
if (font.pointSize() > 0) {
|
||||
font.setPointSize(font.pointSize() + 1);
|
||||
} else {
|
||||
font.setPixelSize(font.pixelSize() + 2);
|
||||
}
|
||||
|
||||
ui->txtCount->setFont(font);
|
||||
ui->txtSize->setFont(font);
|
||||
ui->txtRow->setFont(font);
|
||||
ui->txtCode->setFont(font);
|
||||
ui->txtNote->setFont(font);
|
||||
ui->txtBlank->setFont(font);
|
||||
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(4,7,0))
|
||||
ui->txtFilter->setPlaceholderText("中间空格隔开,例如 *.h *.cpp *.c");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool frmCountCode::checkFile(const QString &fileName)
|
||||
{
|
||||
if (fileName.startsWith("moc_") || fileName.startsWith("ui_") || fileName.startsWith("qrc_")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QFileInfo file(fileName);
|
||||
QString suffix = "*." + file.suffix();
|
||||
QString filter = ui->txtFilter->text().trimmed();
|
||||
QStringList filters = filter.split(" ");
|
||||
return filters.contains(suffix);
|
||||
}
|
||||
|
||||
void frmCountCode::countCode(const QString &filePath)
|
||||
{
|
||||
QDir dir(filePath);
|
||||
foreach (QFileInfo fileInfo , dir.entryInfoList()) {
|
||||
if (fileInfo.isFile()) {
|
||||
QString strFileName = fileInfo.fileName();
|
||||
if (checkFile(strFileName)) {
|
||||
listFile << fileInfo.filePath();
|
||||
}
|
||||
} else {
|
||||
if(fileInfo.fileName() == "." || fileInfo.fileName() == "..") {
|
||||
continue;
|
||||
}
|
||||
|
||||
//递归找出文件
|
||||
countCode(fileInfo.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmCountCode::countCode(const QStringList &files)
|
||||
{
|
||||
int lineCode;
|
||||
int lineBlank;
|
||||
int lineNotes;
|
||||
int count = files.count();
|
||||
on_btnClear_clicked();
|
||||
ui->tableWidget->setRowCount(count);
|
||||
|
||||
quint32 totalLines = 0;
|
||||
quint32 totalBytes = 0;
|
||||
quint32 totalCodes = 0;
|
||||
quint32 totalNotes = 0;
|
||||
quint32 totalBlanks = 0;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
QFileInfo fileInfo(files.at(i));
|
||||
countCode(fileInfo.filePath(), lineCode, lineBlank, lineNotes);
|
||||
int lineAll = lineCode + lineBlank + lineNotes;
|
||||
|
||||
QTableWidgetItem *itemName = new QTableWidgetItem;
|
||||
itemName->setText(fileInfo.fileName());
|
||||
|
||||
QTableWidgetItem *itemSuffix = new QTableWidgetItem;
|
||||
itemSuffix->setText(fileInfo.suffix());
|
||||
|
||||
QTableWidgetItem *itemSize = new QTableWidgetItem;
|
||||
itemSize->setText(QString::number(fileInfo.size()));
|
||||
|
||||
QTableWidgetItem *itemLine = new QTableWidgetItem;
|
||||
itemLine->setText(QString::number(lineAll));
|
||||
|
||||
QTableWidgetItem *itemCode = new QTableWidgetItem;
|
||||
itemCode->setText(QString::number(lineCode));
|
||||
|
||||
QTableWidgetItem *itemNote = new QTableWidgetItem;
|
||||
itemNote->setText(QString::number(lineNotes));
|
||||
|
||||
QTableWidgetItem *itemBlank = new QTableWidgetItem;
|
||||
itemBlank->setText(QString::number(lineBlank));
|
||||
|
||||
QTableWidgetItem *itemPath = new QTableWidgetItem;
|
||||
itemPath->setText(fileInfo.filePath());
|
||||
|
||||
itemSuffix->setTextAlignment(Qt::AlignCenter);
|
||||
itemSize->setTextAlignment(Qt::AlignCenter);
|
||||
itemLine->setTextAlignment(Qt::AlignCenter);
|
||||
itemCode->setTextAlignment(Qt::AlignCenter);
|
||||
itemNote->setTextAlignment(Qt::AlignCenter);
|
||||
itemBlank->setTextAlignment(Qt::AlignCenter);
|
||||
|
||||
ui->tableWidget->setItem(i, 0, itemName);
|
||||
ui->tableWidget->setItem(i, 1, itemSuffix);
|
||||
ui->tableWidget->setItem(i, 2, itemSize);
|
||||
ui->tableWidget->setItem(i, 3, itemLine);
|
||||
ui->tableWidget->setItem(i, 4, itemCode);
|
||||
ui->tableWidget->setItem(i, 5, itemNote);
|
||||
ui->tableWidget->setItem(i, 6, itemBlank);
|
||||
ui->tableWidget->setItem(i, 7, itemPath);
|
||||
|
||||
totalBytes += fileInfo.size();
|
||||
totalLines += lineAll;
|
||||
totalCodes += lineCode;
|
||||
totalNotes += lineNotes;
|
||||
totalBlanks += lineBlank;
|
||||
|
||||
if (i % 100 == 0) {
|
||||
qApp->processEvents();
|
||||
}
|
||||
}
|
||||
|
||||
//显示统计结果
|
||||
listFile.clear();
|
||||
ui->txtCount->setText(QString::number(count));
|
||||
ui->txtSize->setText(QString::number(totalBytes));
|
||||
ui->txtRow->setText(QString::number(totalLines));
|
||||
ui->txtCode->setText(QString::number(totalCodes));
|
||||
ui->txtNote->setText(QString::number(totalNotes));
|
||||
ui->txtBlank->setText(QString::number(totalBlanks));
|
||||
|
||||
//计算百分比
|
||||
double percent = 0.0;
|
||||
//代码行所占百分比
|
||||
percent = ((double)totalCodes / totalLines) * 100;
|
||||
ui->labPercentCode->setText(QString("%1%").arg(percent, 5, 'f', 2, QChar(' ')));
|
||||
//注释行所占百分比
|
||||
percent = ((double)totalNotes / totalLines) * 100;
|
||||
ui->labPercentNote->setText(QString("%1%").arg(percent, 5, 'f', 2, QChar(' ')));
|
||||
//空行所占百分比
|
||||
percent = ((double)totalBlanks / totalLines) * 100;
|
||||
ui->labPercentBlank->setText(QString("%1%").arg(percent, 5, 'f', 2, QChar(' ')));
|
||||
}
|
||||
|
||||
void frmCountCode::countCode(const QString &fileName, int &lineCode, int &lineBlank, int &lineNotes)
|
||||
{
|
||||
lineCode = lineBlank = lineNotes = 0;
|
||||
QFile file(fileName);
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
QTextStream out(&file);
|
||||
QString line;
|
||||
bool isNote = false;
|
||||
while (!out.atEnd()) {
|
||||
line = out.readLine();
|
||||
|
||||
//移除前面的空行
|
||||
if (line.startsWith(" ")) {
|
||||
line.remove(" ");
|
||||
}
|
||||
|
||||
//判断当前行是否是注释
|
||||
if (line.startsWith("/*")) {
|
||||
isNote = true;
|
||||
}
|
||||
|
||||
//注释部分
|
||||
if (isNote) {
|
||||
lineNotes++;
|
||||
} else {
|
||||
if (line.startsWith("//")) { //注释行
|
||||
lineNotes++;
|
||||
} else if (line.isEmpty()) { //空白行
|
||||
lineBlank++;
|
||||
} else { //代码行
|
||||
lineCode++;
|
||||
}
|
||||
}
|
||||
|
||||
//注释结束
|
||||
if (line.endsWith("*/")) {
|
||||
isNote = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmCountCode::on_btnOpenFile_clicked()
|
||||
{
|
||||
QString filter = QString("代码文件(%1)").arg(ui->txtFilter->text().trimmed());
|
||||
QStringList files = QFileDialog::getOpenFileNames(this, "选择文件", "./", filter);
|
||||
if (files.size() > 0) {
|
||||
ui->txtFile->setText(files.join("|"));
|
||||
countCode(files);
|
||||
}
|
||||
}
|
||||
|
||||
void frmCountCode::on_btnOpenPath_clicked()
|
||||
{
|
||||
QString path = QFileDialog::getExistingDirectory(this, "选择目录", "./", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
if (!path.isEmpty()) {
|
||||
ui->txtPath->setText(path);
|
||||
listFile.clear();
|
||||
countCode(path);
|
||||
countCode(listFile);
|
||||
}
|
||||
}
|
||||
|
||||
void frmCountCode::on_btnClear_clicked()
|
||||
{
|
||||
ui->txtCount->setText("0");
|
||||
ui->txtSize->setText("0");
|
||||
ui->txtRow->setText("0");
|
||||
|
||||
ui->txtCode->setText("0");
|
||||
ui->txtNote->setText("0");
|
||||
ui->txtBlank->setText("0");
|
||||
|
||||
ui->labPercentCode->setText("0%");
|
||||
ui->labPercentNote->setText("0%");
|
||||
ui->labPercentBlank->setText("0%");
|
||||
ui->tableWidget->setRowCount(0);
|
||||
}
|
||||
35
countcode/frmcountcode.h
Normal file
35
countcode/frmcountcode.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef FRMCOUNTCODE_H
|
||||
#define FRMCOUNTCODE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class frmCountCode;
|
||||
}
|
||||
|
||||
class frmCountCode : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmCountCode(QWidget *parent = 0);
|
||||
~frmCountCode();
|
||||
|
||||
private:
|
||||
Ui::frmCountCode *ui;
|
||||
QStringList listFile;
|
||||
|
||||
private:
|
||||
void initForm();
|
||||
bool checkFile(const QString &fileName);
|
||||
void countCode(const QString &filePath);
|
||||
void countCode(const QStringList &files);
|
||||
void countCode(const QString &fileName, int &lineCode, int &lineBlank, int &lineNotes);
|
||||
|
||||
private slots:
|
||||
void on_btnOpenFile_clicked();
|
||||
void on_btnOpenPath_clicked();
|
||||
void on_btnClear_clicked();
|
||||
};
|
||||
|
||||
#endif // FRMCOUNTCODE_H
|
||||
411
countcode/frmcountcode.ui
Normal file
411
countcode/frmcountcode.ui
Normal file
@@ -0,0 +1,411 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmCountCode</class>
|
||||
<widget class="QWidget" name="frmCountCode">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidget"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<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 row="0" column="0" rowspan="3">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="3">
|
||||
<widget class="QLineEdit" name="txtCode">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="txtRow">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="txtNote">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLineEdit" name="txtBlank">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="txtCount">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="labPercentCode">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="labBlank">
|
||||
<property name="text">
|
||||
<string>空白行数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="txtSize">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<widget class="QLabel" name="labFilter">
|
||||
<property name="text">
|
||||
<string>过滤</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="labFile">
|
||||
<property name="text">
|
||||
<string>文件</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QLineEdit" name="txtPath">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="6">
|
||||
<widget class="QLineEdit" name="txtFile">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLabel" name="labPath">
|
||||
<property name="text">
|
||||
<string>目录</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6">
|
||||
<widget class="QLineEdit" name="txtFilter">
|
||||
<property name="text">
|
||||
<string>*.h *.cpp *.c *.cs *.java *.js</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="labPercentNote">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QLabel" name="labPercentBlank">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labCount">
|
||||
<property name="text">
|
||||
<string>文件数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="labCode">
|
||||
<property name="text">
|
||||
<string>代码行数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="labNote">
|
||||
<property name="text">
|
||||
<string>注释行数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labSize">
|
||||
<property name="text">
|
||||
<string>字节数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labRow">
|
||||
<property name="text">
|
||||
<string>总行数</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="btnOpenFile">
|
||||
<property name="text">
|
||||
<string>打开文件</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="btnOpenPath">
|
||||
<property name="text">
|
||||
<string>打开目录</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="btnClear">
|
||||
<property name="text">
|
||||
<string>清空结果</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionOpen">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_files.png</normaloff>:/images/toolbar/ic_files.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择文件</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+O</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpenDir">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_folder.png</normaloff>:/images/toolbar/ic_folder.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择目录</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Shift+O</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAbout">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_about.png</normaloff>:/images/toolbar/ic_about.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>关于</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClearModel">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_clean.png</normaloff>:/images/toolbar/ic_clean.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>清空列表</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClearModelLine">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/images/toolbar/ic_delete.png</normaloff>:/images/toolbar/ic_delete.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>删除选中行</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionChinese">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>中文</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnglish">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>English</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUTF8">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>UTF8</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGB18030">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>GB18030</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionQuit">
|
||||
<property name="text">
|
||||
<string>退出</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Q</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>btnOpenFile</tabstop>
|
||||
<tabstop>btnOpenPath</tabstop>
|
||||
<tabstop>btnClear</tabstop>
|
||||
<tabstop>tableWidget</tabstop>
|
||||
<tabstop>txtCount</tabstop>
|
||||
<tabstop>txtSize</tabstop>
|
||||
<tabstop>txtRow</tabstop>
|
||||
<tabstop>txtCode</tabstop>
|
||||
<tabstop>txtNote</tabstop>
|
||||
<tabstop>txtBlank</tabstop>
|
||||
<tabstop>txtFile</tabstop>
|
||||
<tabstop>txtPath</tabstop>
|
||||
<tabstop>txtFilter</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
31
countcode/main.cpp
Normal file
31
countcode/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmcountcode.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmCountCode w;
|
||||
w.setWindowTitle("代码行数统计");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
BIN
countcode/snap.png
Normal file
BIN
countcode/snap.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
296
devicesizetable/devicesizetable.cpp
Normal file
296
devicesizetable/devicesizetable.cpp
Normal file
@@ -0,0 +1,296 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "devicesizetable.h"
|
||||
#include "qprocess.h"
|
||||
#include "qtablewidget.h"
|
||||
#include "qheaderview.h"
|
||||
#include "qfileinfo.h"
|
||||
#include "qdir.h"
|
||||
#include "qprogressbar.h"
|
||||
#include "qtimer.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "windows.h"
|
||||
#endif
|
||||
#define GB (1024 * 1024 * 1024)
|
||||
#define MB (1024 * 1024)
|
||||
#define KB (1024)
|
||||
|
||||
DeviceSizeTable::DeviceSizeTable(QWidget *parent) : QTableWidget(parent)
|
||||
{
|
||||
bgColor = QColor(255, 255, 255);
|
||||
|
||||
chunkColor1 = QColor(100, 184, 255);
|
||||
chunkColor2 = QColor(24, 189, 155);
|
||||
chunkColor3 = QColor(255, 107, 107);
|
||||
|
||||
textColor1 = QColor(10, 10, 10);
|
||||
textColor2 = QColor(255, 255, 255);
|
||||
textColor3 = QColor(255, 255, 255);
|
||||
|
||||
process = new QProcess(this);
|
||||
connect(process, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
|
||||
this->clear();
|
||||
|
||||
//设置列数和列宽
|
||||
this->setColumnCount(5);
|
||||
this->setColumnWidth(0, 100);
|
||||
this->setColumnWidth(1, 120);
|
||||
this->setColumnWidth(2, 120);
|
||||
this->setColumnWidth(3, 120);
|
||||
this->setColumnWidth(4, 120);
|
||||
|
||||
this->setStyleSheet("QTableWidget::item{padding:0px;}");
|
||||
|
||||
QStringList headText;
|
||||
headText << "盘符" << "已用空间" << "可用空间" << "总大小" << "已用百分比" ;
|
||||
|
||||
this->setHorizontalHeaderLabels(headText);
|
||||
this->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
this->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
this->verticalHeader()->setVisible(true);
|
||||
this->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(load()));
|
||||
}
|
||||
|
||||
QColor DeviceSizeTable::getBgColor() const
|
||||
{
|
||||
return this->bgColor;
|
||||
}
|
||||
|
||||
QColor DeviceSizeTable::getChunkColor1() const
|
||||
{
|
||||
return this->chunkColor1;
|
||||
}
|
||||
|
||||
QColor DeviceSizeTable::getChunkColor2() const
|
||||
{
|
||||
return this->chunkColor2;
|
||||
}
|
||||
|
||||
QColor DeviceSizeTable::getChunkColor3() const
|
||||
{
|
||||
return this->chunkColor3;
|
||||
}
|
||||
|
||||
QColor DeviceSizeTable::getTextColor1() const
|
||||
{
|
||||
return this->textColor1;
|
||||
}
|
||||
|
||||
QColor DeviceSizeTable::getTextColor2() const
|
||||
{
|
||||
return this->textColor2;
|
||||
}
|
||||
|
||||
QColor DeviceSizeTable::getTextColor3() const
|
||||
{
|
||||
return this->textColor3;
|
||||
}
|
||||
|
||||
void DeviceSizeTable::load()
|
||||
{
|
||||
//清空原有数据
|
||||
int row = this->rowCount();
|
||||
|
||||
for (int i = 0; i < row; i++) {
|
||||
this->removeRow(0);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QFileInfoList list = QDir::drives();
|
||||
|
||||
foreach (QFileInfo dir, list) {
|
||||
QString dirName = dir.absolutePath();
|
||||
LPCWSTR lpcwstrDriver = (LPCWSTR)dirName.utf16();
|
||||
ULARGE_INTEGER liFreeBytesAvailable, liTotalBytes, liTotalFreeBytes;
|
||||
|
||||
if (GetDiskFreeSpaceEx(lpcwstrDriver, &liFreeBytesAvailable, &liTotalBytes, &liTotalFreeBytes)) {
|
||||
QString use = QString::number((double)(liTotalBytes.QuadPart - liTotalFreeBytes.QuadPart) / GB, 'f', 1);
|
||||
use += "G";
|
||||
QString free = QString::number((double) liTotalFreeBytes.QuadPart / GB, 'f', 1);
|
||||
free += "G";
|
||||
QString all = QString::number((double) liTotalBytes.QuadPart / GB, 'f', 1);
|
||||
all += "G";
|
||||
int percent = 100 - ((double)liTotalFreeBytes.QuadPart / liTotalBytes.QuadPart) * 100;
|
||||
|
||||
insertSize(dirName, use, free, all, percent);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
process->start("df -h");
|
||||
#endif
|
||||
}
|
||||
|
||||
void DeviceSizeTable::setBgColor(const QColor &bgColor)
|
||||
{
|
||||
if (this->bgColor != bgColor) {
|
||||
this->bgColor = bgColor;
|
||||
this->load();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSizeTable::setChunkColor1(const QColor &chunkColor1)
|
||||
{
|
||||
if (this->chunkColor1 != chunkColor1) {
|
||||
this->chunkColor1 = chunkColor1;
|
||||
this->load();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSizeTable::setChunkColor2(const QColor &chunkColor2)
|
||||
{
|
||||
if (this->chunkColor2 != chunkColor2) {
|
||||
this->chunkColor2 = chunkColor2;
|
||||
this->load();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSizeTable::setChunkColor3(const QColor &chunkColor3)
|
||||
{
|
||||
if (this->chunkColor3 != chunkColor3) {
|
||||
this->chunkColor3 = chunkColor3;
|
||||
this->load();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSizeTable::setTextColor1(const QColor &textColor1)
|
||||
{
|
||||
if (this->textColor1 != textColor1) {
|
||||
this->textColor1 = textColor1;
|
||||
this->load();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSizeTable::setTextColor2(const QColor &textColor2)
|
||||
{
|
||||
if (this->textColor2 != textColor2) {
|
||||
this->textColor2 = textColor2;
|
||||
this->load();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSizeTable::setTextColor3(const QColor &textColor3)
|
||||
{
|
||||
if (this->textColor3 != textColor3) {
|
||||
this->textColor3 = textColor3;
|
||||
this->load();
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSizeTable::readData()
|
||||
{
|
||||
while (!process->atEnd()) {
|
||||
QString result = QLatin1String(process->readLine());
|
||||
#ifdef __arm__
|
||||
if (result.startsWith("/dev/root")) {
|
||||
checkSize(result, "本地存储");
|
||||
} else if (result.startsWith("/dev/mmcblk")) {
|
||||
checkSize(result, "本地存储");
|
||||
} else if (result.startsWith("/dev/mmcblk1p")) {
|
||||
checkSize(result, "SD卡");
|
||||
QStringList list = result.split(" ");
|
||||
emit sdcardReceive(list.at(0));
|
||||
} else if (result.startsWith("/dev/sd")) {
|
||||
checkSize(result, "U盘");
|
||||
QStringList list = result.split(" ");
|
||||
emit udiskReceive(list.at(0));
|
||||
}
|
||||
#else
|
||||
if (result.startsWith("/dev/sd")) {
|
||||
checkSize(result, "");
|
||||
QStringList list = result.split(" ");
|
||||
emit udiskReceive(list.at(0));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSizeTable::checkSize(const QString &result, const QString &name)
|
||||
{
|
||||
QString dev, use, free, all;
|
||||
int percent = 0;
|
||||
QStringList list = result.split(" ");
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < list.count(); i++) {
|
||||
QString s = list.at(i).trimmed();
|
||||
|
||||
if (s == "") {
|
||||
continue;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (index == 1) {
|
||||
dev = s;
|
||||
} else if (index == 2) {
|
||||
all = s;
|
||||
} else if (index == 3) {
|
||||
use = s;
|
||||
} else if (index == 4) {
|
||||
free = s;
|
||||
} else if (index == 5) {
|
||||
percent = s.left(s.length() - 1).toInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (name.length() > 0) {
|
||||
dev = name;
|
||||
}
|
||||
|
||||
insertSize(dev, use, free, all, percent);
|
||||
}
|
||||
|
||||
void DeviceSizeTable::insertSize(const QString &name, const QString &use, const QString &free, const QString &all, int percent)
|
||||
{
|
||||
int row = this->rowCount();
|
||||
this->insertRow(row);
|
||||
|
||||
QTableWidgetItem *itemname = new QTableWidgetItem(name);
|
||||
QTableWidgetItem *itemuse = new QTableWidgetItem(use);
|
||||
itemuse->setTextAlignment(Qt::AlignCenter);
|
||||
QTableWidgetItem *itemfree = new QTableWidgetItem(free);
|
||||
itemfree->setTextAlignment(Qt::AlignCenter);
|
||||
QTableWidgetItem *itemall = new QTableWidgetItem(all);
|
||||
itemall->setTextAlignment(Qt::AlignCenter);
|
||||
|
||||
this->setItem(row, 0, itemname);
|
||||
this->setItem(row, 1, itemuse);
|
||||
this->setItem(row, 2, itemfree);
|
||||
this->setItem(row, 3, itemall);
|
||||
|
||||
QProgressBar *bar = new QProgressBar;
|
||||
bar->setRange(0, 100);
|
||||
bar->setValue(percent);
|
||||
|
||||
QString qss = QString("QProgressBar{background:%1;border-width:0px;border-radius:0px;text-align:center;}"
|
||||
"QProgressBar::chunk{border-radius:0px;}").arg(bgColor.name());
|
||||
|
||||
if (percent < 50) {
|
||||
qss += QString("QProgressBar{color:%1;}QProgressBar::chunk{background:%2;}").arg(textColor1.name()).arg(chunkColor1.name());
|
||||
} else if (percent < 90) {
|
||||
qss += QString("QProgressBar{color:%1;}QProgressBar::chunk{background:%2;}").arg(textColor2.name()).arg(chunkColor2.name());
|
||||
} else {
|
||||
qss += QString("QProgressBar{color:%1;}QProgressBar::chunk{background:%2;}").arg(textColor3.name()).arg(chunkColor3.name());
|
||||
}
|
||||
|
||||
bar->setStyleSheet(qss);
|
||||
this->setCellWidget(row, 4, bar);
|
||||
}
|
||||
|
||||
QSize DeviceSizeTable::sizeHint() const
|
||||
{
|
||||
return QSize(500, 300);
|
||||
}
|
||||
|
||||
QSize DeviceSizeTable::minimumSizeHint() const
|
||||
{
|
||||
return QSize(200, 150);
|
||||
}
|
||||
91
devicesizetable/devicesizetable.h
Normal file
91
devicesizetable/devicesizetable.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef DEVICESIZETABLE_H
|
||||
#define DEVICESIZETABLE_H
|
||||
|
||||
/**
|
||||
* 本地存储空间大小控件 作者:feiyangqingyun(QQ:517216493) 2016-11-30
|
||||
* 1:可自动加载本地存储设备的总容量/已用容量
|
||||
* 2:进度条显示已用容量
|
||||
* 3:支持所有操作系统
|
||||
* 4:增加U盘或者SD卡到达信号
|
||||
*/
|
||||
|
||||
#include <QTableWidget>
|
||||
|
||||
class QProcess;
|
||||
|
||||
#ifdef quc
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT DeviceSizeTable : public QTableWidget
|
||||
#else
|
||||
class DeviceSizeTable : public QTableWidget
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor)
|
||||
Q_PROPERTY(QColor chunkColor1 READ getChunkColor1 WRITE setChunkColor1)
|
||||
Q_PROPERTY(QColor chunkColor2 READ getChunkColor2 WRITE setChunkColor2)
|
||||
Q_PROPERTY(QColor chunkColor3 READ getChunkColor3 WRITE setChunkColor3)
|
||||
Q_PROPERTY(QColor textColor1 READ getTextColor1 WRITE setTextColor1)
|
||||
Q_PROPERTY(QColor textColor2 READ getTextColor2 WRITE setTextColor2)
|
||||
Q_PROPERTY(QColor textColor3 READ getTextColor3 WRITE setTextColor3)
|
||||
|
||||
public:
|
||||
explicit DeviceSizeTable(QWidget *parent = 0);
|
||||
|
||||
private:
|
||||
QProcess *process; //执行命令进程
|
||||
|
||||
QColor bgColor; //背景颜色
|
||||
QColor chunkColor1; //进度颜色1
|
||||
QColor chunkColor2; //进度颜色2
|
||||
QColor chunkColor3; //进度颜色3
|
||||
QColor textColor1; //文字颜色1
|
||||
QColor textColor2; //文字颜色2
|
||||
QColor textColor3; //文字颜色3
|
||||
|
||||
private slots:
|
||||
void readData();
|
||||
void checkSize(const QString &result, const QString &name);
|
||||
void insertSize(const QString &name, const QString &use, const QString &free, const QString &all, int percent);
|
||||
|
||||
public:
|
||||
QColor getBgColor() const;
|
||||
QColor getChunkColor1() const;
|
||||
QColor getChunkColor2() const;
|
||||
QColor getChunkColor3() const;
|
||||
QColor getTextColor1() const;
|
||||
QColor getTextColor2() const;
|
||||
QColor getTextColor3() const;
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
//载入容量
|
||||
void load();
|
||||
|
||||
//设置背景颜色
|
||||
void setBgColor(const QColor &bgColor);
|
||||
|
||||
//设置进度颜色
|
||||
void setChunkColor1(const QColor &chunkColor1);
|
||||
void setChunkColor2(const QColor &chunkColor2);
|
||||
void setChunkColor3(const QColor &chunkColor3);
|
||||
|
||||
//设置文字颜色
|
||||
void setTextColor1(const QColor &textColor1);
|
||||
void setTextColor2(const QColor &textColor2);
|
||||
void setTextColor3(const QColor &textColor3);
|
||||
|
||||
Q_SIGNALS:
|
||||
void sdcardReceive(const QString &sdcardName);
|
||||
void udiskReceive(const QString &udiskName);
|
||||
};
|
||||
|
||||
#endif // DEVICESIZETABLE_H
|
||||
23
devicesizetable/devicesizetable.pro
Normal file
23
devicesizetable/devicesizetable.pro
Normal file
@@ -0,0 +1,23 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2017-02-08T10:02:20
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = devicesizetable
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmdevicesizetable.cpp
|
||||
SOURCES += devicesizetable.cpp
|
||||
|
||||
HEADERS += frmdevicesizetable.h
|
||||
HEADERS += devicesizetable.h
|
||||
|
||||
FORMS += frmdevicesizetable.ui
|
||||
14
devicesizetable/frmdevicesizetable.cpp
Normal file
14
devicesizetable/frmdevicesizetable.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmdevicesizetable.h"
|
||||
#include "ui_frmdevicesizetable.h"
|
||||
|
||||
frmDeviceSizeTable::frmDeviceSizeTable(QWidget *parent) : QWidget(parent), ui(new Ui::frmDeviceSizeTable)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
frmDeviceSizeTable::~frmDeviceSizeTable()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
23
devicesizetable/frmdevicesizetable.h
Normal file
23
devicesizetable/frmdevicesizetable.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef FRMDEVICESIZETABLE_H
|
||||
#define FRMDEVICESIZETABLE_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class frmDeviceSizeTable;
|
||||
}
|
||||
|
||||
class frmDeviceSizeTable : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmDeviceSizeTable(QWidget *parent = 0);
|
||||
~frmDeviceSizeTable();
|
||||
|
||||
private:
|
||||
Ui::frmDeviceSizeTable *ui;
|
||||
};
|
||||
|
||||
#endif // FRMDEVICESIZETABLE_H
|
||||
122
devicesizetable/frmdevicesizetable.ui
Normal file
122
devicesizetable/frmdevicesizetable.ui
Normal file
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmDeviceSizeTable</class>
|
||||
<widget class="QWidget" name="frmDeviceSizeTable">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="DeviceSizeTable" name="tableWidget">
|
||||
<row/>
|
||||
<row/>
|
||||
<row/>
|
||||
<row/>
|
||||
<row/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<item row="0" column="0"/>
|
||||
<item row="0" column="1">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="1" column="0"/>
|
||||
<item row="1" column="1">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="2" column="0"/>
|
||||
<item row="2" column="1">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="3" column="0"/>
|
||||
<item row="3" column="1">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="4" column="0"/>
|
||||
<item row="4" column="1">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<property name="textAlignment">
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DeviceSizeTable</class>
|
||||
<extends>QTableWidget</extends>
|
||||
<header>devicesizetable.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
31
devicesizetable/main.cpp
Normal file
31
devicesizetable/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmdevicesizetable.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmDeviceSizeTable w;
|
||||
w.setWindowTitle("本地存储空间大小控件");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
190
flatui/flatui.cpp
Normal file
190
flatui/flatui.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "flatui.h"
|
||||
#include "qmutex.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"
|
||||
|
||||
QScopedPointer<FlatUI> FlatUI::self;
|
||||
FlatUI *FlatUI::Instance()
|
||||
{
|
||||
if (self.isNull()) {
|
||||
static QMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
if (self.isNull()) {
|
||||
self.reset(new FlatUI);
|
||||
}
|
||||
}
|
||||
|
||||
return self.data();
|
||||
}
|
||||
|
||||
FlatUI::FlatUI(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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{font:%1pt;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;
|
||||
}
|
||||
BIN
flatui/flatui.gif
Normal file
BIN
flatui/flatui.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 223 KiB |
99
flatui/flatui.h
Normal file
99
flatui/flatui.h
Normal file
@@ -0,0 +1,99 @@
|
||||
#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
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT FlatUI : public QObject
|
||||
#else
|
||||
class FlatUI : public QObject
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static FlatUI *Instance();
|
||||
explicit FlatUI(QObject *parent = 0);
|
||||
|
||||
private:
|
||||
static QScopedPointer<FlatUI> self;
|
||||
|
||||
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 = 9, //文字字号
|
||||
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
|
||||
23
flatui/flatui.pro
Normal file
23
flatui/flatui.pro
Normal file
@@ -0,0 +1,23 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2017-01-09T09:29:12
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = flatui
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmflatui.cpp
|
||||
SOURCES += flatui.cpp
|
||||
|
||||
HEADERS += frmflatui.h
|
||||
HEADERS += flatui.h
|
||||
|
||||
FORMS += frmflatui.ui
|
||||
99
flatui/frmflatui.cpp
Normal file
99
flatui/frmflatui.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmflatui.h"
|
||||
#include "ui_frmflatui.h"
|
||||
#include "flatui.h"
|
||||
#include "qdebug.h"
|
||||
#include "qdesktopwidget.h"
|
||||
#include "qdatetime.h"
|
||||
|
||||
frmFlatUI::frmFlatUI(QWidget *parent) : QWidget(parent), ui(new Ui::frmFlatUI)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
}
|
||||
|
||||
frmFlatUI::~frmFlatUI()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmFlatUI::initForm()
|
||||
{
|
||||
ui->bar1->setRange(0, 100);
|
||||
ui->bar2->setRange(0, 100);
|
||||
ui->slider1->setRange(0, 100);
|
||||
ui->slider2->setRange(0, 100);
|
||||
|
||||
connect(ui->slider1, SIGNAL(valueChanged(int)), ui->bar1, SLOT(setValue(int)));
|
||||
connect(ui->slider2, SIGNAL(valueChanged(int)), ui->bar2, SLOT(setValue(int)));
|
||||
ui->slider1->setValue(30);
|
||||
ui->slider2->setValue(30);
|
||||
|
||||
this->setStyleSheet("*{outline:0px;}QWidget#frmFlatUI{background:#FFFFFF;}");
|
||||
|
||||
FlatUI::Instance()->setPushButtonQss(ui->btn1);
|
||||
FlatUI::Instance()->setPushButtonQss(ui->btn2, 5, 8, "#1ABC9C", "#E6F8F5", "#2EE1C1", "#FFFFFF", "#16A086", "#A7EEE6");
|
||||
FlatUI::Instance()->setPushButtonQss(ui->btn3, 5, 8, "#3498DB", "#FFFFFF", "#5DACE4", "#E5FEFF", "#2483C7", "#A0DAFB");
|
||||
FlatUI::Instance()->setPushButtonQss(ui->btn4, 5, 8, "#E74C3C", "#FFFFFF", "#EC7064", "#FFF5E7", "#DC2D1A", "#F5A996");
|
||||
|
||||
FlatUI::Instance()->setLineEditQss(ui->txt1);
|
||||
FlatUI::Instance()->setLineEditQss(ui->txt2, 5, 2, "#DCE4EC", "#1ABC9C");
|
||||
FlatUI::Instance()->setLineEditQss(ui->txt3, 3, 1, "#DCE4EC", "#3498DB");
|
||||
FlatUI::Instance()->setLineEditQss(ui->txt4, 3, 1, "#DCE4EC", "#E74C3C");
|
||||
|
||||
FlatUI::Instance()->setProgressQss(ui->bar1);
|
||||
FlatUI::Instance()->setProgressQss(ui->bar2, 8, 5, 9, "#E8EDF2", "#1ABC9C");
|
||||
|
||||
FlatUI::Instance()->setSliderQss(ui->slider1);
|
||||
FlatUI::Instance()->setSliderQss(ui->slider2, 10, "#E8EDF2", "#E74C3C", "#E74C3C");
|
||||
FlatUI::Instance()->setSliderQss(ui->slider3, 10, "#E8EDF2", "#34495E", "#34495E");
|
||||
|
||||
FlatUI::Instance()->setRadioButtonQss(ui->rbtn1);
|
||||
FlatUI::Instance()->setRadioButtonQss(ui->rbtn2, 8, "#D7DBDE", "#1ABC9C");
|
||||
FlatUI::Instance()->setRadioButtonQss(ui->rbtn3, 8, "#D7DBDE", "#3498DB");
|
||||
FlatUI::Instance()->setRadioButtonQss(ui->rbtn4, 8, "#D7DBDE", "#E74C3C");
|
||||
|
||||
FlatUI::Instance()->setScrollBarQss(ui->horizontalScrollBar);
|
||||
FlatUI::Instance()->setScrollBarQss(ui->verticalScrollBar, 8, 120, 20, "#606060", "#34495E", "#1ABC9C", "#E74C3C");
|
||||
|
||||
//设置列数和列宽
|
||||
int width = qApp->desktop()->availableGeometry().width() - 120;
|
||||
ui->tableWidget->setColumnCount(5);
|
||||
ui->tableWidget->setColumnWidth(0, width * 0.06);
|
||||
ui->tableWidget->setColumnWidth(1, width * 0.10);
|
||||
ui->tableWidget->setColumnWidth(2, width * 0.06);
|
||||
ui->tableWidget->setColumnWidth(3, width * 0.10);
|
||||
ui->tableWidget->setColumnWidth(4, width * 0.20);
|
||||
ui->tableWidget->verticalHeader()->setDefaultSectionSize(25);
|
||||
|
||||
QStringList headText;
|
||||
headText << "设备编号" << "设备名称" << "设备地址" << "告警内容" << "告警时间";
|
||||
ui->tableWidget->setHorizontalHeaderLabels(headText);
|
||||
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
ui->tableWidget->setAlternatingRowColors(true);
|
||||
ui->tableWidget->verticalHeader()->setVisible(false);
|
||||
ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
//设置行高
|
||||
ui->tableWidget->setRowCount(300);
|
||||
|
||||
for (int i = 0; i < 300; i++) {
|
||||
ui->tableWidget->setRowHeight(i, 24);
|
||||
|
||||
QTableWidgetItem *itemDeviceID = new QTableWidgetItem(QString::number(i + 1));
|
||||
QTableWidgetItem *itemDeviceName = new QTableWidgetItem(QString("测试设备%1").arg(i + 1));
|
||||
QTableWidgetItem *itemDeviceAddr = new QTableWidgetItem(QString::number(i + 1));
|
||||
QTableWidgetItem *itemContent = new QTableWidgetItem("防区告警");
|
||||
QTableWidgetItem *itemTime = new QTableWidgetItem(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
|
||||
|
||||
ui->tableWidget->setItem(i, 0, itemDeviceID);
|
||||
ui->tableWidget->setItem(i, 1, itemDeviceName);
|
||||
ui->tableWidget->setItem(i, 2, itemDeviceAddr);
|
||||
ui->tableWidget->setItem(i, 3, itemContent);
|
||||
ui->tableWidget->setItem(i, 4, itemTime);
|
||||
}
|
||||
|
||||
}
|
||||
26
flatui/frmflatui.h
Normal file
26
flatui/frmflatui.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef FRMFLATUI_H
|
||||
#define FRMFLATUI_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class frmFlatUI;
|
||||
}
|
||||
|
||||
class frmFlatUI : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmFlatUI(QWidget *parent = 0);
|
||||
~frmFlatUI();
|
||||
|
||||
private:
|
||||
Ui::frmFlatUI *ui;
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
};
|
||||
|
||||
#endif // FRMFLATUI_H
|
||||
203
flatui/frmflatui.ui
Normal file
203
flatui/frmflatui.ui
Normal file
@@ -0,0 +1,203 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmFlatUI</class>
|
||||
<widget class="QWidget" name="frmFlatUI">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>450</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="7" column="0">
|
||||
<widget class="QRadioButton" name="rbtn1">
|
||||
<property name="text">
|
||||
<string>语文</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="btn3">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>测试按钮</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="txt3"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="btn2">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>测试按钮</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4" rowspan="9">
|
||||
<widget class="QSlider" name="slider3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QRadioButton" name="rbtn2">
|
||||
<property name="text">
|
||||
<string>英语</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QProgressBar" name="bar2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="4">
|
||||
<widget class="QScrollBar" name="horizontalScrollBar">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<widget class="QRadioButton" name="rbtn4">
|
||||
<property name="text">
|
||||
<string>历史</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QRadioButton" name="rbtn3">
|
||||
<property name="text">
|
||||
<string>数学</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="btn4">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>测试按钮</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="txt2"/>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="txt4"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="btn1">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>测试按钮</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLineEdit" name="txt1"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QProgressBar" name="bar1">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5" rowspan="9">
|
||||
<widget class="QScrollBar" name="verticalScrollBar">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QSlider" name="slider1">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2" colspan="2">
|
||||
<widget class="QSlider" name="slider2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>255</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="6">
|
||||
<widget class="QTableWidget" name="tableWidget">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="gridStyle">
|
||||
<enum>Qt::DashDotLine</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
31
flatui/main.cpp
Normal file
31
flatui/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmflatui.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmFlatUI w;
|
||||
w.setWindowTitle("FlatUI控件集合");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
803
gifwidget/gif.h
Normal file
803
gifwidget/gif.h
Normal file
@@ -0,0 +1,803 @@
|
||||
//
|
||||
// gif.h
|
||||
// by Charlie Tangora
|
||||
// Public domain.
|
||||
// Email me : ctangora -at- gmail -dot- com
|
||||
//
|
||||
// This file offers a simple, very limited way to create animated GIFs directly in code.
|
||||
//
|
||||
// Those looking for particular cleverness are likely to be disappointed; it's pretty
|
||||
// much a straight-ahead implementation of the GIF format with optional Floyd-Steinberg
|
||||
// dithering. (It does at least use delta encoding - only the changed portions of each
|
||||
// frame are saved.)
|
||||
//
|
||||
// So resulting files are often quite large. The hope is that it will be handy nonetheless
|
||||
// as a quick and easily-integrated way for programs to spit out animations.
|
||||
//
|
||||
// Only RGBA8 is currently supported as an input format. (The alpha is ignored.)
|
||||
//
|
||||
// USAGE:
|
||||
// Create a GifWriter struct. Pass it to GifBegin() to initialize and write the header.
|
||||
// Pass subsequent frames to GifWriteFrame().
|
||||
// Finally, call GifEnd() to close the file handle and free memory.
|
||||
//
|
||||
|
||||
#ifndef __gif_h__
|
||||
#define __gif_h__
|
||||
|
||||
#include <stdio.h> // for FILE*
|
||||
#include <string.h> // for memcpy and bzero
|
||||
#include <stdint.h> // for integer typedefs
|
||||
|
||||
// Define these macros to hook into a custom memory allocator.
|
||||
// TEMP_MALLOC and TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs
|
||||
// and any temp memory allocated by a function will be freed before it exits.
|
||||
// MALLOC and FREE are used only by GifBegin and GifEnd respectively (to allocate a buffer the size of the image, which
|
||||
// is used to find changed pixels for delta-encoding.)
|
||||
|
||||
#ifndef GIF_TEMP_MALLOC
|
||||
#include <stdlib.h>
|
||||
#define GIF_TEMP_MALLOC malloc
|
||||
#endif
|
||||
|
||||
#ifndef GIF_TEMP_FREE
|
||||
#include <stdlib.h>
|
||||
#define GIF_TEMP_FREE free
|
||||
#endif
|
||||
|
||||
#ifndef GIF_MALLOC
|
||||
#include <stdlib.h>
|
||||
#define GIF_MALLOC malloc
|
||||
#endif
|
||||
|
||||
#ifndef GIF_FREE
|
||||
#include <stdlib.h>
|
||||
#define GIF_FREE free
|
||||
#endif
|
||||
|
||||
class Gif
|
||||
{
|
||||
public:
|
||||
int kGifTransIndex;
|
||||
struct GifPalette {
|
||||
int bitDepth;
|
||||
uint8_t r[256];
|
||||
uint8_t g[256];
|
||||
uint8_t b[256];
|
||||
// k-d tree over RGB space, organized in heap fashion
|
||||
// i.e. left child of node i is node i*2, right child is node i*2+1
|
||||
// nodes 256-511 are implicitly the leaves, containing a color
|
||||
uint8_t treeSplitElt[255];
|
||||
uint8_t treeSplit[255];
|
||||
};
|
||||
|
||||
// max, min, and abs functions
|
||||
int GifIMax(int l, int r)
|
||||
{
|
||||
return l > r ? l : r;
|
||||
}
|
||||
int GifIMin(int l, int r)
|
||||
{
|
||||
return l < r ? l : r;
|
||||
}
|
||||
int GifIAbs(int i)
|
||||
{
|
||||
return i < 0 ? -i : i;
|
||||
}
|
||||
|
||||
// walks the k-d tree to pick the palette entry for a desired color.
|
||||
// Takes as in/out parameters the current best color and its error -
|
||||
// only changes them if it finds a better color in its subtree.
|
||||
// this is the major hotspot in the code at the moment.
|
||||
void GifGetClosestPaletteColor(GifPalette *pPal, int r, int g, int b, int &bestInd, int &bestDiff, int treeRoot = 1)
|
||||
{
|
||||
// base case, reached the bottom of the tree
|
||||
if(treeRoot > (1 << pPal->bitDepth) - 1) {
|
||||
int ind = treeRoot - (1 << pPal->bitDepth);
|
||||
if(ind == kGifTransIndex) {
|
||||
return;
|
||||
}
|
||||
// check whether this color is better than the current winner
|
||||
int r_err = r - ((int32_t)pPal->r[ind]);
|
||||
int g_err = g - ((int32_t)pPal->g[ind]);
|
||||
int b_err = b - ((int32_t)pPal->b[ind]);
|
||||
int diff = GifIAbs(r_err) + GifIAbs(g_err) + GifIAbs(b_err);
|
||||
if(diff < bestDiff) {
|
||||
bestInd = ind;
|
||||
bestDiff = diff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// take the appropriate color (r, g, or b) for this node of the k-d tree
|
||||
int comps[3];
|
||||
comps[0] = r;
|
||||
comps[1] = g;
|
||||
comps[2] = b;
|
||||
int splitComp = comps[pPal->treeSplitElt[treeRoot]];
|
||||
|
||||
int splitPos = pPal->treeSplit[treeRoot];
|
||||
if(splitPos > splitComp) {
|
||||
// check the left subtree
|
||||
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2);
|
||||
if( bestDiff > splitPos - splitComp ) {
|
||||
// cannot prove there's not a better value in the right subtree, check that too
|
||||
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2 + 1);
|
||||
}
|
||||
} else {
|
||||
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2 + 1);
|
||||
if( bestDiff > splitComp - splitPos ) {
|
||||
GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GifSwapPixels(uint8_t *image, int pixA, int pixB)
|
||||
{
|
||||
uint8_t rA = image[pixA * 4];
|
||||
uint8_t gA = image[pixA * 4 + 1];
|
||||
uint8_t bA = image[pixA * 4 + 2];
|
||||
uint8_t aA = image[pixA * 4 + 3];
|
||||
|
||||
uint8_t rB = image[pixB * 4];
|
||||
uint8_t gB = image[pixB * 4 + 1];
|
||||
uint8_t bB = image[pixB * 4 + 2];
|
||||
uint8_t aB = image[pixA * 4 + 3];
|
||||
|
||||
image[pixA * 4] = rB;
|
||||
image[pixA * 4 + 1] = gB;
|
||||
image[pixA * 4 + 2] = bB;
|
||||
image[pixA * 4 + 3] = aB;
|
||||
|
||||
image[pixB * 4] = rA;
|
||||
image[pixB * 4 + 1] = gA;
|
||||
image[pixB * 4 + 2] = bA;
|
||||
image[pixB * 4 + 3] = aA;
|
||||
}
|
||||
|
||||
// just the partition operation from quicksort
|
||||
int GifPartition(uint8_t *image, const int left, const int right, const int elt, int pivotIndex)
|
||||
{
|
||||
const int pivotValue = image[(pivotIndex) * 4 + elt];
|
||||
GifSwapPixels(image, pivotIndex, right - 1);
|
||||
int storeIndex = left;
|
||||
bool split = 0;
|
||||
for(int ii = left; ii < right - 1; ++ii) {
|
||||
int arrayVal = image[ii * 4 + elt];
|
||||
if( arrayVal < pivotValue ) {
|
||||
GifSwapPixels(image, ii, storeIndex);
|
||||
++storeIndex;
|
||||
} else if( arrayVal == pivotValue ) {
|
||||
if(split) {
|
||||
GifSwapPixels(image, ii, storeIndex);
|
||||
++storeIndex;
|
||||
}
|
||||
split = !split;
|
||||
}
|
||||
}
|
||||
GifSwapPixels(image, storeIndex, right - 1);
|
||||
return storeIndex;
|
||||
}
|
||||
|
||||
// Perform an incomplete sort, finding all elements above and below the desired median
|
||||
void GifPartitionByMedian(uint8_t *image, int left, int right, int com, int neededCenter)
|
||||
{
|
||||
if (left < right - 1) {
|
||||
int pivotIndex = left + (right - left) / 2;
|
||||
pivotIndex = GifPartition(image, left, right, com, pivotIndex);
|
||||
// Only "sort" the section of the array that contains the median
|
||||
if(pivotIndex > neededCenter) {
|
||||
GifPartitionByMedian(image, left, pivotIndex, com, neededCenter);
|
||||
}
|
||||
if(pivotIndex < neededCenter) {
|
||||
GifPartitionByMedian(image, pivotIndex + 1, right, com, neededCenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Builds a palette by creating a balanced k-d tree of all pixels in the image
|
||||
void GifSplitPalette(uint8_t *image,
|
||||
int numPixels, int firstElt,
|
||||
int lastElt, int splitElt,
|
||||
int splitDist, int treeNode,
|
||||
bool buildForDither, GifPalette *pal)
|
||||
{
|
||||
if (lastElt <= firstElt || numPixels == 0) {
|
||||
return;
|
||||
}
|
||||
// base case, bottom of the tree
|
||||
if (lastElt == firstElt + 1) {
|
||||
if (buildForDither) {
|
||||
// Dithering needs at least one color as dark as anything
|
||||
// in the image and at least one brightest color -
|
||||
// otherwise it builds up error and produces strange artifacts
|
||||
if( firstElt == 1 ) {
|
||||
// special case: the darkest color in the image
|
||||
uint32_t r = 255, g = 255, b = 255;
|
||||
for(int ii = 0; ii < numPixels; ++ii) {
|
||||
r = (uint32_t)GifIMin((int32_t)r, image[ii * 4 + 0]);
|
||||
g = (uint32_t)GifIMin((int32_t)g, image[ii * 4 + 1]);
|
||||
b = (uint32_t)GifIMin((int32_t)b, image[ii * 4 + 2]);
|
||||
}
|
||||
pal->r[firstElt] = (uint8_t)r;
|
||||
pal->g[firstElt] = (uint8_t)g;
|
||||
pal->b[firstElt] = (uint8_t)b;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( firstElt == (1 << pal->bitDepth) - 1 ) {
|
||||
// special case: the lightest color in the image
|
||||
uint32_t r = 0, g = 0, b = 0;
|
||||
for(int ii = 0; ii < numPixels; ++ii) {
|
||||
r = (uint32_t)GifIMax((int32_t)r, image[ii * 4 + 0]);
|
||||
g = (uint32_t)GifIMax((int32_t)g, image[ii * 4 + 1]);
|
||||
b = (uint32_t)GifIMax((int32_t)b, image[ii * 4 + 2]);
|
||||
}
|
||||
pal->r[firstElt] = (uint8_t)r;
|
||||
pal->g[firstElt] = (uint8_t)g;
|
||||
pal->b[firstElt] = (uint8_t)b;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// otherwise, take the average of all colors in this subcube
|
||||
uint64_t r = 0, g = 0, b = 0;
|
||||
for (int ii = 0; ii < numPixels; ++ii) {
|
||||
r += image[ii * 4 + 0];
|
||||
g += image[ii * 4 + 1];
|
||||
b += image[ii * 4 + 2];
|
||||
}
|
||||
|
||||
r += (uint64_t)numPixels / 2; // round to nearest
|
||||
g += (uint64_t)numPixels / 2;
|
||||
b += (uint64_t)numPixels / 2;
|
||||
|
||||
r /= (uint64_t)numPixels;
|
||||
g /= (uint64_t)numPixels;
|
||||
b /= (uint64_t)numPixels;
|
||||
|
||||
pal->r[firstElt] = (uint8_t)r;
|
||||
pal->g[firstElt] = (uint8_t)g;
|
||||
pal->b[firstElt] = (uint8_t)b;
|
||||
return;
|
||||
}
|
||||
// Find the axis with the largest range
|
||||
int minR = 255, maxR = 0;
|
||||
int minG = 255, maxG = 0;
|
||||
int minB = 255, maxB = 0;
|
||||
for(int ii = 0; ii < numPixels; ++ii) {
|
||||
int r = image[ii * 4 + 0];
|
||||
int g = image[ii * 4 + 1];
|
||||
int b = image[ii * 4 + 2];
|
||||
|
||||
if(r > maxR) {
|
||||
maxR = r;
|
||||
}
|
||||
if(r < minR) {
|
||||
minR = r;
|
||||
}
|
||||
|
||||
if(g > maxG) {
|
||||
maxG = g;
|
||||
}
|
||||
if(g < minG) {
|
||||
minG = g;
|
||||
}
|
||||
|
||||
if(b > maxB) {
|
||||
maxB = b;
|
||||
}
|
||||
if(b < minB) {
|
||||
minB = b;
|
||||
}
|
||||
}
|
||||
|
||||
int rRange = maxR - minR;
|
||||
int gRange = maxG - minG;
|
||||
int bRange = maxB - minB;
|
||||
// and split along that axis. (incidentally, this means this isn't a "proper" k-d tree but I don't know what else to call it)
|
||||
int splitCom = 1;
|
||||
if (bRange > gRange) {
|
||||
splitCom = 2;
|
||||
}
|
||||
if (rRange > bRange && rRange > gRange) {
|
||||
splitCom = 0;
|
||||
}
|
||||
|
||||
int subPixelsA = numPixels * (splitElt - firstElt) / (lastElt - firstElt);
|
||||
int subPixelsB = numPixels - subPixelsA;
|
||||
|
||||
GifPartitionByMedian(image, 0, numPixels, splitCom, subPixelsA);
|
||||
|
||||
pal->treeSplitElt[treeNode] = (uint8_t)splitCom;
|
||||
pal->treeSplit[treeNode] = image[subPixelsA * 4 + splitCom];
|
||||
|
||||
GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt - splitDist, splitDist / 2, treeNode * 2, buildForDither, pal);
|
||||
GifSplitPalette(image + subPixelsA * 4, subPixelsB, splitElt, lastElt, splitElt + splitDist, splitDist / 2, treeNode * 2 + 1, buildForDither, pal);
|
||||
}
|
||||
|
||||
// Finds all pixels that have changed from the previous image and
|
||||
// moves them to the fromt of th buffer.
|
||||
// This allows us to build a palette optimized for the colors of the
|
||||
// changed pixels only.
|
||||
int GifPickChangedPixels( const uint8_t *lastFrame, uint8_t *frame, int numPixels )
|
||||
{
|
||||
int numChanged = 0;
|
||||
uint8_t *writeIter = frame;
|
||||
for (int ii = 0; ii < numPixels; ++ii) {
|
||||
if(lastFrame[0] != frame[0] ||
|
||||
lastFrame[1] != frame[1] ||
|
||||
lastFrame[2] != frame[2]) {
|
||||
writeIter[0] = frame[0];
|
||||
writeIter[1] = frame[1];
|
||||
writeIter[2] = frame[2];
|
||||
++numChanged;
|
||||
writeIter += 4;
|
||||
}
|
||||
lastFrame += 4;
|
||||
frame += 4;
|
||||
}
|
||||
return numChanged;
|
||||
}
|
||||
|
||||
// Creates a palette by placing all the image pixels in a k-d tree and then averaging the blocks at the bottom.
|
||||
// This is known as the "modified median split" technique
|
||||
void GifMakePalette( const uint8_t *lastFrame,
|
||||
const uint8_t *nextFrame,
|
||||
uint32_t width, uint32_t height,
|
||||
int bitDepth, bool buildForDither,
|
||||
GifPalette *pPal )
|
||||
{
|
||||
pPal->bitDepth = bitDepth;
|
||||
|
||||
// SplitPalette is destructive (it sorts the pixels by color) so
|
||||
// we must create a copy of the image for it to destroy
|
||||
size_t imageSize = (size_t)(width * height * 4 * sizeof(uint8_t));
|
||||
uint8_t *destroyableImage = (uint8_t *)GIF_TEMP_MALLOC(imageSize);
|
||||
memcpy(destroyableImage, nextFrame, imageSize);
|
||||
|
||||
int numPixels = (int)(width * height);
|
||||
if(lastFrame) {
|
||||
numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels);
|
||||
}
|
||||
|
||||
const int lastElt = 1 << bitDepth;
|
||||
const int splitElt = lastElt / 2;
|
||||
const int splitDist = splitElt / 2;
|
||||
|
||||
GifSplitPalette(destroyableImage, numPixels, 1, lastElt, splitElt, splitDist, 1, buildForDither, pPal);
|
||||
|
||||
GIF_TEMP_FREE(destroyableImage);
|
||||
|
||||
// add the bottom node for the transparency index
|
||||
pPal->treeSplit[1 << (bitDepth - 1)] = 0;
|
||||
pPal->treeSplitElt[1 << (bitDepth - 1)] = 0;
|
||||
|
||||
pPal->r[0] = pPal->g[0] = pPal->b[0] = 0;
|
||||
}
|
||||
|
||||
// Implements Floyd-Steinberg dithering, writes palette value to alpha
|
||||
void GifDitherImage( const uint8_t *lastFrame, const uint8_t *nextFrame,
|
||||
uint8_t *outFrame, uint32_t width,
|
||||
uint32_t height, GifPalette *pPal )
|
||||
{
|
||||
int numPixels = (int)(width * height);
|
||||
|
||||
// quantPixels initially holds color*256 for all pixels
|
||||
// The extra 8 bits of precision allow for sub-single-color error values
|
||||
// to be propagated
|
||||
int32_t *quantPixels = (int32_t *)GIF_TEMP_MALLOC(sizeof(int32_t) * (size_t)numPixels * 4);
|
||||
for( int ii = 0; ii < numPixels * 4; ++ii ) {
|
||||
uint8_t pix = nextFrame[ii];
|
||||
int32_t pix16 = int32_t(pix) * 256;
|
||||
quantPixels[ii] = pix16;
|
||||
}
|
||||
|
||||
for( uint32_t yy = 0; yy < height; ++yy ) {
|
||||
for( uint32_t xx = 0; xx < width; ++xx ) {
|
||||
int32_t *nextPix = quantPixels + 4 * (yy * width + xx);
|
||||
const uint8_t *lastPix = lastFrame ? lastFrame + 4 * (yy * width + xx) : NULL;
|
||||
// Compute the colors we want (rounding to nearest)
|
||||
int32_t rr = (nextPix[0] + 127) / 256;
|
||||
int32_t gg = (nextPix[1] + 127) / 256;
|
||||
int32_t bb = (nextPix[2] + 127) / 256;
|
||||
// if it happens that we want the color from last frame, then just write out
|
||||
// a transparent pixel
|
||||
if( lastFrame &&
|
||||
lastPix[0] == rr &&
|
||||
lastPix[1] == gg &&
|
||||
lastPix[2] == bb ) {
|
||||
nextPix[0] = rr;
|
||||
nextPix[1] = gg;
|
||||
nextPix[2] = bb;
|
||||
nextPix[3] = kGifTransIndex;
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t bestDiff = 1000000;
|
||||
int32_t bestInd = kGifTransIndex;
|
||||
// Search the palete
|
||||
GifGetClosestPaletteColor(pPal, rr, gg, bb, bestInd, bestDiff);
|
||||
// Write the result to the temp buffer
|
||||
int32_t r_err = nextPix[0] - int32_t(pPal->r[bestInd]) * 256;
|
||||
int32_t g_err = nextPix[1] - int32_t(pPal->g[bestInd]) * 256;
|
||||
int32_t b_err = nextPix[2] - int32_t(pPal->b[bestInd]) * 256;
|
||||
|
||||
nextPix[0] = pPal->r[bestInd];
|
||||
nextPix[1] = pPal->g[bestInd];
|
||||
nextPix[2] = pPal->b[bestInd];
|
||||
nextPix[3] = bestInd;
|
||||
|
||||
// Propagate the error to the four adjacent locations
|
||||
// that we haven't touched yet
|
||||
int quantloc_7 = (int)(yy * width + xx + 1);
|
||||
int quantloc_3 = (int)(yy * width + width + xx - 1);
|
||||
int quantloc_5 = (int)(yy * width + width + xx);
|
||||
int quantloc_1 = (int)(yy * width + width + xx + 1);
|
||||
|
||||
if(quantloc_7 < numPixels) {
|
||||
int32_t *pix7 = quantPixels + 4 * quantloc_7;
|
||||
pix7[0] += GifIMax( -pix7[0], r_err * 7 / 16 );
|
||||
pix7[1] += GifIMax( -pix7[1], g_err * 7 / 16 );
|
||||
pix7[2] += GifIMax( -pix7[2], b_err * 7 / 16 );
|
||||
}
|
||||
|
||||
if(quantloc_3 < numPixels) {
|
||||
int32_t *pix3 = quantPixels + 4 * quantloc_3;
|
||||
pix3[0] += GifIMax( -pix3[0], r_err * 3 / 16 );
|
||||
pix3[1] += GifIMax( -pix3[1], g_err * 3 / 16 );
|
||||
pix3[2] += GifIMax( -pix3[2], b_err * 3 / 16 );
|
||||
}
|
||||
|
||||
if(quantloc_5 < numPixels) {
|
||||
int32_t *pix5 = quantPixels + 4 * quantloc_5;
|
||||
pix5[0] += GifIMax( -pix5[0], r_err * 5 / 16 );
|
||||
pix5[1] += GifIMax( -pix5[1], g_err * 5 / 16 );
|
||||
pix5[2] += GifIMax( -pix5[2], b_err * 5 / 16 );
|
||||
}
|
||||
|
||||
if(quantloc_1 < numPixels) {
|
||||
int32_t *pix1 = quantPixels + 4 * quantloc_1;
|
||||
pix1[0] += GifIMax( -pix1[0], r_err / 16 );
|
||||
pix1[1] += GifIMax( -pix1[1], g_err / 16 );
|
||||
pix1[2] += GifIMax( -pix1[2], b_err / 16 );
|
||||
}
|
||||
}
|
||||
}
|
||||
// Copy the palettized result to the output buffer
|
||||
for( int ii = 0; ii < numPixels * 4; ++ii ) {
|
||||
outFrame[ii] = (uint8_t)quantPixels[ii];
|
||||
}
|
||||
|
||||
GIF_TEMP_FREE(quantPixels);
|
||||
}
|
||||
|
||||
// Picks palette colors for the image using simple thresholding, no dithering
|
||||
void GifThresholdImage( const uint8_t *lastFrame, const uint8_t *nextFrame,
|
||||
uint8_t *outFrame, uint32_t width, uint32_t height,
|
||||
GifPalette *pPal )
|
||||
{
|
||||
uint32_t numPixels = width * height;
|
||||
for( uint32_t ii = 0; ii < numPixels; ++ii ) {
|
||||
// if a previous color is available, and it matches the current color,
|
||||
// set the pixel to transparent
|
||||
if(lastFrame &&
|
||||
lastFrame[0] == nextFrame[0] &&
|
||||
lastFrame[1] == nextFrame[1] &&
|
||||
lastFrame[2] == nextFrame[2]) {
|
||||
outFrame[0] = lastFrame[0];
|
||||
outFrame[1] = lastFrame[1];
|
||||
outFrame[2] = lastFrame[2];
|
||||
outFrame[3] = kGifTransIndex;
|
||||
} else {
|
||||
// palettize the pixel
|
||||
int32_t bestDiff = 1000000;
|
||||
int32_t bestInd = 1;
|
||||
GifGetClosestPaletteColor(pPal, nextFrame[0], nextFrame[1], nextFrame[2], bestInd, bestDiff);
|
||||
|
||||
// Write the resulting color to the output buffer
|
||||
outFrame[0] = pPal->r[bestInd];
|
||||
outFrame[1] = pPal->g[bestInd];
|
||||
outFrame[2] = pPal->b[bestInd];
|
||||
outFrame[3] = (uint8_t)bestInd;
|
||||
}
|
||||
if(lastFrame) {
|
||||
lastFrame += 4;
|
||||
}
|
||||
outFrame += 4;
|
||||
nextFrame += 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Simple structure to write out the LZW-compressed portion of the image
|
||||
// one bit at a time
|
||||
struct GifBitStatus {
|
||||
uint8_t bitIndex; // how many bits in the partial byte written so far
|
||||
uint8_t byte; // current partial byte
|
||||
|
||||
uint32_t chunkIndex;
|
||||
uint8_t chunk[256]; // bytes are written in here until we have 256 of them, then written to the file
|
||||
};
|
||||
|
||||
// insert a single bit
|
||||
void GifWriteBit( GifBitStatus &stat, uint32_t bit )
|
||||
{
|
||||
bit = bit & 1;
|
||||
bit = bit << stat.bitIndex;
|
||||
stat.byte |= bit;
|
||||
|
||||
++stat.bitIndex;
|
||||
if( stat.bitIndex > 7 ) {
|
||||
// move the newly-finished byte to the chunk buffer
|
||||
stat.chunk[stat.chunkIndex++] = stat.byte;
|
||||
// and start a new byte
|
||||
stat.bitIndex = 0;
|
||||
stat.byte = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// write all bytes so far to the file
|
||||
void GifWriteChunk( FILE *f, GifBitStatus &stat )
|
||||
{
|
||||
fputc((int)stat.chunkIndex, f);
|
||||
fwrite(stat.chunk, 1, stat.chunkIndex, f);
|
||||
|
||||
stat.bitIndex = 0;
|
||||
stat.byte = 0;
|
||||
stat.chunkIndex = 0;
|
||||
}
|
||||
|
||||
void GifWriteCode( FILE *f, GifBitStatus &stat, uint32_t code, uint32_t length )
|
||||
{
|
||||
for( uint32_t ii = 0; ii < length; ++ii ) {
|
||||
GifWriteBit(stat, code);
|
||||
code = code >> 1;
|
||||
if( stat.chunkIndex == 255 ) {
|
||||
GifWriteChunk(f, stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The LZW dictionary is a 256-ary tree constructed as the file is encoded,
|
||||
// this is one node
|
||||
struct GifLzwNode {
|
||||
uint16_t m_next[256];
|
||||
};
|
||||
|
||||
// write a 256-color (8-bit) image palette to the file
|
||||
void GifWritePalette( const GifPalette *pPal, FILE *f )
|
||||
{
|
||||
fputc(0, f); // first color: transparency
|
||||
fputc(0, f);
|
||||
fputc(0, f);
|
||||
for(int ii = 1; ii < (1 << pPal->bitDepth); ++ii) {
|
||||
uint32_t r = pPal->r[ii];
|
||||
uint32_t g = pPal->g[ii];
|
||||
uint32_t b = pPal->b[ii];
|
||||
fputc((int)r, f);
|
||||
fputc((int)g, f);
|
||||
fputc((int)b, f);
|
||||
}
|
||||
}
|
||||
|
||||
// write the image header, LZW-compress and write out the image
|
||||
void GifWriteLzwImage(FILE *f, uint8_t *image, uint32_t left,
|
||||
uint32_t top, uint32_t width,
|
||||
uint32_t height, uint32_t delay,
|
||||
GifPalette *pPal)
|
||||
{
|
||||
// graphics control extension
|
||||
fputc(0x21, f);
|
||||
fputc(0xf9, f);
|
||||
fputc(0x04, f);
|
||||
fputc(0x05, f); // leave prev frame in place, this frame has transparency
|
||||
fputc(delay & 0xff, f);
|
||||
fputc((delay >> 8) & 0xff, f);
|
||||
fputc(kGifTransIndex, f); // transparent color index
|
||||
fputc(0, f);
|
||||
|
||||
fputc(0x2c, f); // image descriptor block
|
||||
|
||||
fputc(left & 0xff, f); // corner of image in canvas space
|
||||
fputc((left >> 8) & 0xff, f);
|
||||
fputc(top & 0xff, f);
|
||||
fputc((top >> 8) & 0xff, f);
|
||||
|
||||
fputc(width & 0xff, f); // width and height of image
|
||||
fputc((width >> 8) & 0xff, f);
|
||||
fputc(height & 0xff, f);
|
||||
fputc((height >> 8) & 0xff, f);
|
||||
|
||||
//fputc(0, f); // no local color table, no transparency
|
||||
//fputc(0x80, f); // no local color table, but transparency
|
||||
|
||||
fputc(0x80 + pPal->bitDepth - 1, f); // local color table present, 2 ^ bitDepth entries
|
||||
GifWritePalette(pPal, f);
|
||||
|
||||
const int minCodeSize = pPal->bitDepth;
|
||||
const uint32_t clearCode = 1 << pPal->bitDepth;
|
||||
|
||||
fputc(minCodeSize, f); // min code size 8 bits
|
||||
|
||||
GifLzwNode *codetree = (GifLzwNode *)GIF_TEMP_MALLOC(sizeof(GifLzwNode) * 4096);
|
||||
|
||||
memset(codetree, 0, sizeof(GifLzwNode) * 4096);
|
||||
int32_t curCode = -1;
|
||||
uint32_t codeSize = (uint32_t)minCodeSize + 1;
|
||||
uint32_t maxCode = clearCode + 1;
|
||||
|
||||
GifBitStatus stat;
|
||||
stat.byte = 0;
|
||||
stat.bitIndex = 0;
|
||||
stat.chunkIndex = 0;
|
||||
|
||||
GifWriteCode(f, stat, clearCode, codeSize); // start with a fresh LZW dictionary
|
||||
|
||||
for(uint32_t yy = 0; yy < height; ++yy) {
|
||||
for(uint32_t xx = 0; xx < width; ++xx) {
|
||||
uint8_t nextValue = image[(yy * width + xx) * 4 + 3];
|
||||
// "loser mode" - no compression, every single code is followed immediately by a clear
|
||||
//WriteCode( f, stat, nextValue, codeSize );
|
||||
//WriteCode( f, stat, 256, codeSize );
|
||||
if( curCode < 0 ) {
|
||||
// first value in a new run
|
||||
curCode = nextValue;
|
||||
} else if( codetree[curCode].m_next[nextValue] ) {
|
||||
// current run already in the dictionary
|
||||
curCode = codetree[curCode].m_next[nextValue];
|
||||
} else {
|
||||
// finish the current run, write a code
|
||||
GifWriteCode(f, stat, (uint32_t)curCode, codeSize);
|
||||
// insert the new run into the dictionary
|
||||
codetree[curCode].m_next[nextValue] = (uint16_t)++maxCode;
|
||||
if( maxCode >= (1ul << codeSize) ) {
|
||||
// dictionary entry count has broken a size barrier,
|
||||
// we need more bits for codes
|
||||
codeSize++;
|
||||
}
|
||||
if( maxCode == 4095 ) {
|
||||
// the dictionary is full, clear it out and begin anew
|
||||
GifWriteCode(f, stat, clearCode, codeSize); // clear tree
|
||||
|
||||
memset(codetree, 0, sizeof(GifLzwNode) * 4096);
|
||||
codeSize = (uint32_t)(minCodeSize + 1);
|
||||
maxCode = clearCode + 1;
|
||||
}
|
||||
curCode = nextValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// compression footer
|
||||
GifWriteCode(f, stat, (uint32_t)curCode, codeSize);
|
||||
GifWriteCode(f, stat, clearCode, codeSize);
|
||||
GifWriteCode(f, stat, clearCode + 1, (uint32_t)minCodeSize + 1);
|
||||
// write out the last partial chunk
|
||||
while( stat.bitIndex ) {
|
||||
GifWriteBit(stat, 0);
|
||||
}
|
||||
if( stat.chunkIndex ) {
|
||||
GifWriteChunk(f, stat);
|
||||
}
|
||||
|
||||
fputc(0, f); // image block terminator
|
||||
|
||||
GIF_TEMP_FREE(codetree);
|
||||
}
|
||||
|
||||
struct GifWriter {
|
||||
FILE *f;
|
||||
uint8_t *oldImage;
|
||||
bool firstFrame;
|
||||
};
|
||||
|
||||
// Creates a gif file.
|
||||
// The input GIFWriter is assumed to be uninitialized.
|
||||
// The delay value is the time between frames in hundredths of a second - note that not all viewers pay much attention to this value.
|
||||
bool GifBegin( GifWriter *writer, const char *filename,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t delay, int32_t bitDepth = 8,
|
||||
bool dither = false )
|
||||
{
|
||||
(void)bitDepth;
|
||||
(void)dither; // Mute "Unused argument" warnings
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
writer->f = 0;
|
||||
fopen_s(&writer->f, filename, "wb");
|
||||
#else
|
||||
writer->f = fopen(filename, "wb");
|
||||
#endif
|
||||
if(!writer->f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
writer->firstFrame = true;
|
||||
|
||||
// allocate
|
||||
writer->oldImage = (uint8_t *)GIF_MALLOC(width * height * 4);
|
||||
fputs("GIF89a", writer->f);
|
||||
|
||||
// screen descriptor
|
||||
fputc(width & 0xff, writer->f);
|
||||
fputc((width >> 8) & 0xff, writer->f);
|
||||
fputc(height & 0xff, writer->f);
|
||||
fputc((height >> 8) & 0xff, writer->f);
|
||||
|
||||
fputc(0xf0, writer->f); // there is an unsorted global color table of 2 entries
|
||||
fputc(0, writer->f); // background color
|
||||
fputc(0, writer->f); // pixels are square (we need to specify this because it's 1989)
|
||||
|
||||
// now the "global" palette (really just a dummy palette)
|
||||
// color 0: black
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
// color 1: also black
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
fputc(0, writer->f);
|
||||
|
||||
if( delay != 0 ) {
|
||||
// animation header
|
||||
fputc(0x21, writer->f); // extension
|
||||
fputc(0xff, writer->f); // application specific
|
||||
fputc(11, writer->f); // length 11
|
||||
fputs("NETSCAPE2.0", writer->f); // yes, really
|
||||
fputc(3, writer->f); // 3 bytes of NETSCAPE2.0 data
|
||||
|
||||
fputc(1, writer->f); // JUST BECAUSE
|
||||
fputc(0, writer->f); // loop infinitely (byte 0)
|
||||
fputc(0, writer->f); // loop infinitely (byte 1)
|
||||
|
||||
fputc(0, writer->f); // block terminator
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Writes out a new frame to a GIF in progress.
|
||||
// The GIFWriter should have been created by GIFBegin.
|
||||
// AFAIK, it is legal to use different bit depths for different frames of an image -
|
||||
// this may be handy to save bits in animations that don't change much.
|
||||
bool GifWriteFrame( GifWriter *writer, const uint8_t *image,
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t delay, int bitDepth = 8, bool dither = false )
|
||||
{
|
||||
if(!writer->f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *oldImage = writer->firstFrame ? NULL : writer->oldImage;
|
||||
writer->firstFrame = false;
|
||||
|
||||
GifPalette pal;
|
||||
GifMakePalette((dither ? NULL : oldImage), image, width, height, bitDepth, dither, &pal);
|
||||
|
||||
if(dither) {
|
||||
GifDitherImage(oldImage, image, writer->oldImage, width, height, &pal);
|
||||
} else {
|
||||
GifThresholdImage(oldImage, image, writer->oldImage, width, height, &pal);
|
||||
}
|
||||
|
||||
GifWriteLzwImage(writer->f, writer->oldImage, 0, 0, width, height, delay, &pal);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Writes the EOF code, closes the file handle, and frees temp memory used by a GIF.
|
||||
// Many if not most viewers will still display a GIF properly if the EOF code is missing,
|
||||
// but it's still a good idea to write it out.
|
||||
bool GifEnd( GifWriter *writer )
|
||||
{
|
||||
if(!writer->f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fputc(0x3b, writer->f); // end of file
|
||||
fclose(writer->f);
|
||||
GIF_FREE(writer->oldImage);
|
||||
|
||||
writer->f = NULL;
|
||||
writer->oldImage = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
363
gifwidget/gifwidget.cpp
Normal file
363
gifwidget/gifwidget.cpp
Normal file
@@ -0,0 +1,363 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "gifwidget.h"
|
||||
#include "qmutex.h"
|
||||
#include "qlabel.h"
|
||||
#include "qlineedit.h"
|
||||
#include "qpushbutton.h"
|
||||
#include "qlayout.h"
|
||||
#include "qpainter.h"
|
||||
#include "qevent.h"
|
||||
#include "qstyle.h"
|
||||
#include "qpixmap.h"
|
||||
#include "qtimer.h"
|
||||
#include "qdatetime.h"
|
||||
#include "qapplication.h"
|
||||
#include "qdesktopwidget.h"
|
||||
#include "qdesktopservices.h"
|
||||
#include "qfiledialog.h"
|
||||
#include "qurl.h"
|
||||
#include "qdebug.h"
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
|
||||
#include "qscreen.h"
|
||||
#endif
|
||||
|
||||
QScopedPointer<GifWidget> GifWidget::self;
|
||||
GifWidget *GifWidget::Instance()
|
||||
{
|
||||
if (self.isNull()) {
|
||||
static QMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
if (self.isNull()) {
|
||||
self.reset(new GifWidget);
|
||||
}
|
||||
}
|
||||
|
||||
return self.data();
|
||||
}
|
||||
|
||||
GifWidget::GifWidget(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
this->initControl();
|
||||
this->initForm();
|
||||
}
|
||||
|
||||
bool GifWidget::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
static QPoint mousePoint;
|
||||
static bool mousePressed = false;
|
||||
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (mouseEvent->type() == QEvent::MouseButtonPress) {
|
||||
if (mouseEvent->button() == Qt::LeftButton) {
|
||||
mousePressed = true;
|
||||
mousePoint = mouseEvent->globalPos() - this->pos();
|
||||
return true;
|
||||
}
|
||||
} else if (mouseEvent->type() == QEvent::MouseButtonRelease) {
|
||||
mousePressed = false;
|
||||
return true;
|
||||
} else if (mouseEvent->type() == QEvent::MouseMove) {
|
||||
if (mousePressed && (mouseEvent->buttons() && Qt::LeftButton)) {
|
||||
this->move(mouseEvent->globalPos() - mousePoint);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void GifWidget::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
//拉动右下角改变大小自动赋值
|
||||
txtWidth->setText(QString::number(widgetMain->width()));
|
||||
txtHeight->setText(QString::number(widgetMain->height()));
|
||||
QDialog::resizeEvent(e);
|
||||
}
|
||||
|
||||
void GifWidget::paintEvent(QPaintEvent *)
|
||||
{
|
||||
int width = txtWidth->text().toInt();
|
||||
int height = txtHeight->text().toInt();
|
||||
rectGif = QRect(borderWidth, widgetTop->height(), width - (borderWidth * 2), height);
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(bgColor);
|
||||
painter.drawRoundedRect(this->rect(), 5, 5);
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Clear);
|
||||
painter.fillRect(rectGif, Qt::SolidPattern);
|
||||
}
|
||||
|
||||
int GifWidget::getBorderWidth() const
|
||||
{
|
||||
return this->borderWidth;
|
||||
}
|
||||
|
||||
QColor GifWidget::getBgColor() const
|
||||
{
|
||||
return this->bgColor;
|
||||
}
|
||||
|
||||
void GifWidget::initControl()
|
||||
{
|
||||
this->setObjectName("GifWidget");
|
||||
this->resize(800, 600);
|
||||
this->setSizeGripEnabled(true);
|
||||
QVBoxLayout *verticalLayout = new QVBoxLayout(this);
|
||||
verticalLayout->setSpacing(0);
|
||||
verticalLayout->setContentsMargins(11, 11, 11, 11);
|
||||
verticalLayout->setObjectName("verticalLayout");
|
||||
verticalLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
widgetTop = new QWidget(this);
|
||||
widgetTop->setObjectName("widgetTop");
|
||||
widgetTop->setMinimumSize(QSize(0, 35));
|
||||
widgetTop->setMaximumSize(QSize(16777215, 35));
|
||||
|
||||
QHBoxLayout *layoutTop = new QHBoxLayout(widgetTop);
|
||||
layoutTop->setSpacing(0);
|
||||
layoutTop->setContentsMargins(11, 11, 11, 11);
|
||||
layoutTop->setObjectName("layoutTop");
|
||||
layoutTop->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
QPushButton *btnIcon = new QPushButton(widgetTop);
|
||||
btnIcon->setObjectName("btnIcon");
|
||||
QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
sizePolicy.setHorizontalStretch(0);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
sizePolicy.setHeightForWidth(btnIcon->sizePolicy().hasHeightForWidth());
|
||||
btnIcon->setSizePolicy(sizePolicy);
|
||||
btnIcon->setMinimumSize(QSize(35, 0));
|
||||
btnIcon->setFlat(true);
|
||||
layoutTop->addWidget(btnIcon);
|
||||
|
||||
QLabel *labTitle = new QLabel(widgetTop);
|
||||
labTitle->setObjectName("labTitle");
|
||||
layoutTop->addWidget(labTitle);
|
||||
|
||||
QSpacerItem *horizontalSpacer = new QSpacerItem(87, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
layoutTop->addItem(horizontalSpacer);
|
||||
|
||||
QPushButton *btnClose = new QPushButton(widgetTop);
|
||||
btnClose->setObjectName("btnClose");
|
||||
sizePolicy.setHeightForWidth(btnClose->sizePolicy().hasHeightForWidth());
|
||||
btnClose->setSizePolicy(sizePolicy);
|
||||
btnClose->setMinimumSize(QSize(35, 0));
|
||||
btnClose->setFocusPolicy(Qt::NoFocus);
|
||||
btnClose->setFlat(true);
|
||||
layoutTop->addWidget(btnClose);
|
||||
verticalLayout->addWidget(widgetTop);
|
||||
|
||||
widgetMain = new QWidget(this);
|
||||
widgetMain->setObjectName("widgetMain");
|
||||
QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Expanding);
|
||||
sizePolicy1.setHorizontalStretch(0);
|
||||
sizePolicy1.setVerticalStretch(0);
|
||||
sizePolicy1.setHeightForWidth(widgetMain->sizePolicy().hasHeightForWidth());
|
||||
widgetMain->setSizePolicy(sizePolicy1);
|
||||
verticalLayout->addWidget(widgetMain);
|
||||
|
||||
widgetBottom = new QWidget(this);
|
||||
widgetBottom->setObjectName("widgetBottom");
|
||||
widgetBottom->setMinimumSize(QSize(0, 45));
|
||||
widgetBottom->setMaximumSize(QSize(16777215, 45));
|
||||
|
||||
QHBoxLayout *layoutBottom = new QHBoxLayout(widgetBottom);
|
||||
layoutBottom->setSpacing(6);
|
||||
layoutBottom->setContentsMargins(11, 11, 11, 11);
|
||||
layoutBottom->setObjectName("layoutBottom");
|
||||
layoutBottom->setContentsMargins(9, 9, -1, -1);
|
||||
|
||||
QLabel *labFps = new QLabel(widgetBottom);
|
||||
labFps->setObjectName("labFps");
|
||||
layoutBottom->addWidget(labFps);
|
||||
|
||||
txtFps = new QLineEdit(widgetBottom);
|
||||
txtFps->setObjectName("txtFps");
|
||||
txtFps->setMaximumSize(QSize(50, 16777215));
|
||||
txtFps->setAlignment(Qt::AlignCenter);
|
||||
layoutBottom->addWidget(txtFps);
|
||||
|
||||
QLabel *labWidth = new QLabel(widgetBottom);
|
||||
labWidth->setObjectName("labWidth");
|
||||
layoutBottom->addWidget(labWidth);
|
||||
|
||||
txtWidth = new QLineEdit(widgetBottom);
|
||||
txtWidth->setObjectName("txtWidth");
|
||||
txtWidth->setEnabled(true);
|
||||
txtWidth->setMaximumSize(QSize(50, 16777215));
|
||||
txtWidth->setAlignment(Qt::AlignCenter);
|
||||
layoutBottom->addWidget(txtWidth);
|
||||
|
||||
QLabel *labHeight = new QLabel(widgetBottom);
|
||||
labHeight->setObjectName("labHeight");
|
||||
layoutBottom->addWidget(labHeight);
|
||||
|
||||
txtHeight = new QLineEdit(widgetBottom);
|
||||
txtHeight->setObjectName("txtHeight");
|
||||
txtHeight->setEnabled(true);
|
||||
txtHeight->setMaximumSize(QSize(50, 16777215));
|
||||
txtHeight->setAlignment(Qt::AlignCenter);
|
||||
layoutBottom->addWidget(txtHeight);
|
||||
|
||||
labStatus = new QLabel(widgetBottom);
|
||||
labStatus->setObjectName("labStatus");
|
||||
QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
sizePolicy2.setHorizontalStretch(0);
|
||||
sizePolicy2.setVerticalStretch(0);
|
||||
sizePolicy2.setHeightForWidth(labStatus->sizePolicy().hasHeightForWidth());
|
||||
labStatus->setSizePolicy(sizePolicy2);
|
||||
labStatus->setAlignment(Qt::AlignCenter);
|
||||
layoutBottom->addWidget(labStatus);
|
||||
|
||||
btnStart = new QPushButton(widgetBottom);
|
||||
btnStart->setObjectName("btnStart");
|
||||
sizePolicy.setHeightForWidth(btnStart->sizePolicy().hasHeightForWidth());
|
||||
btnStart->setSizePolicy(sizePolicy);
|
||||
layoutBottom->addWidget(btnStart);
|
||||
verticalLayout->addWidget(widgetBottom);
|
||||
|
||||
labTitle->setText("GIF录屏工具(QQ:517216493)");
|
||||
labFps->setText("帧率");
|
||||
labWidth->setText("宽度");
|
||||
labHeight->setText("高度");
|
||||
btnStart->setText("开始");
|
||||
this->setWindowTitle(labTitle->text());
|
||||
|
||||
btnIcon->setIcon(style()->standardIcon(QStyle::SP_ComputerIcon));
|
||||
btnClose->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
|
||||
|
||||
connect(btnClose, SIGNAL(clicked(bool)), this, SLOT(closeAll()));
|
||||
connect(btnStart, SIGNAL(clicked(bool)), this, SLOT(record()));
|
||||
connect(txtWidth, SIGNAL(editingFinished()), this, SLOT(resizeForm()));
|
||||
connect(txtHeight, SIGNAL(editingFinished()), this, SLOT(resizeForm()));
|
||||
}
|
||||
|
||||
void GifWidget::initForm()
|
||||
{
|
||||
borderWidth = 3;
|
||||
bgColor = QColor(34, 163, 169);
|
||||
|
||||
fps = 10;
|
||||
txtFps->setText(QString::number(fps));
|
||||
gifWriter = 0;
|
||||
|
||||
timer = new QTimer(this);
|
||||
timer->setInterval(100);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(saveImage()));
|
||||
|
||||
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowStaysOnTopHint);
|
||||
this->installEventFilter(this);
|
||||
|
||||
QStringList qss;
|
||||
qss.append("QLabel{color:#ffffff;}");
|
||||
qss.append("#btnClose,#btnIcon{border:none;border-radius:0px;}");
|
||||
qss.append("#btnClose:hover{background-color:#ff0000;}");
|
||||
qss.append("#btnClose{border-top-right-radius:5px;}");
|
||||
qss.append("#labTitle{font:bold 16px;}");
|
||||
qss.append("#labStatus{font:15px;}");
|
||||
this->setStyleSheet(qss.join(""));
|
||||
}
|
||||
|
||||
void GifWidget::saveImage()
|
||||
{
|
||||
if (!gifWriter) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
//由于qt4没有RGBA8888,采用最接近RGBA8888的是ARGB32,颜色会有点偏差
|
||||
QPixmap pix = QPixmap::grabWindow(0, x() + rectGif.x(), y() + rectGif.y(), rectGif.width(), rectGif.height());
|
||||
QImage image = pix.toImage().convertToFormat(QImage::Format_ARGB32);
|
||||
#else
|
||||
QScreen *screen = QApplication::primaryScreen();
|
||||
QPixmap pix = screen->grabWindow(0, x() + rectGif.x(), y() + rectGif.y(), rectGif.width(), rectGif.height());
|
||||
QImage image = pix.toImage().convertToFormat(QImage::Format_RGBA8888);
|
||||
#endif
|
||||
|
||||
gif.GifWriteFrame(gifWriter, image.bits(), rectGif.width(), rectGif.height(), fps);
|
||||
count++;
|
||||
labStatus->setText(QString("正在录制 第 %1 帧").arg(count));
|
||||
}
|
||||
|
||||
void GifWidget::record()
|
||||
{
|
||||
if (btnStart->text() == "开始") {
|
||||
if (0 != gifWriter) {
|
||||
delete gifWriter;
|
||||
gifWriter = 0;
|
||||
}
|
||||
|
||||
//先弹出文件保存对话框
|
||||
//fileName = qApp->applicationDirPath() + "/" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss.gif");
|
||||
fileName = QFileDialog::getSaveFileName(this, "选择保存位置", qApp->applicationDirPath() + "/", "gif图片(*.gif)");
|
||||
if (fileName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int width = txtWidth->text().toInt();
|
||||
int height = txtHeight->text().toInt();
|
||||
fps = txtFps->text().toInt();
|
||||
|
||||
gifWriter = new Gif::GifWriter;
|
||||
bool bOk = gif.GifBegin(gifWriter, fileName.toLocal8Bit().data(), width, height, fps);
|
||||
if (!bOk) {
|
||||
delete gifWriter;
|
||||
gifWriter = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
labStatus->setText("开始录制...");
|
||||
btnStart->setText("停止");
|
||||
//延时启动
|
||||
timer->setInterval(1000 / fps);
|
||||
QTimer::singleShot(1000, timer, SLOT(start()));
|
||||
//saveImage();
|
||||
} else {
|
||||
timer->stop();
|
||||
gif.GifEnd(gifWriter);
|
||||
|
||||
delete gifWriter;
|
||||
gifWriter = 0;
|
||||
|
||||
labStatus->setText(QString("录制完成 共 %1 帧").arg(count));
|
||||
btnStart->setText("开始");
|
||||
QDesktopServices::openUrl(QUrl(fileName));
|
||||
}
|
||||
}
|
||||
|
||||
void GifWidget::closeAll()
|
||||
{
|
||||
if (0 != gifWriter) {
|
||||
delete gifWriter;
|
||||
gifWriter = 0;
|
||||
}
|
||||
|
||||
this->close();
|
||||
}
|
||||
|
||||
void GifWidget::resizeForm()
|
||||
{
|
||||
int width = txtWidth->text().toInt();
|
||||
int height = txtHeight->text().toInt();
|
||||
this->resize(width, height + widgetTop->height() + widgetBottom->height());
|
||||
}
|
||||
|
||||
void GifWidget::setBorderWidth(int borderWidth)
|
||||
{
|
||||
if (this->borderWidth != borderWidth) {
|
||||
this->borderWidth = borderWidth;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void GifWidget::setBgColor(const QColor &bgColor)
|
||||
{
|
||||
if (this->bgColor != bgColor) {
|
||||
this->bgColor = bgColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
85
gifwidget/gifwidget.h
Normal file
85
gifwidget/gifwidget.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef GIFWIDGET_H
|
||||
#define GIFWIDGET_H
|
||||
|
||||
/**
|
||||
* GIF录屏控件 作者:feiyangqingyun(QQ:517216493) 2019-4-3
|
||||
* 1:可设置要录制屏幕的宽高,支持右下角直接拉动改变.
|
||||
* 2:可设置变宽的宽度
|
||||
* 3:可设置录屏控件的背景颜色
|
||||
* 4:可设置录制的帧数
|
||||
* 5:录制区域可自由拖动选择
|
||||
*/
|
||||
|
||||
#include <QDialog>
|
||||
#include "gif.h"
|
||||
|
||||
class QLineEdit;
|
||||
class QLabel;
|
||||
|
||||
#ifdef quc
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT GifWidget : public QDialog
|
||||
#else
|
||||
class GifWidget : public QDialog
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int borderWidth READ getBorderWidth WRITE setBorderWidth)
|
||||
Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor)
|
||||
|
||||
public:
|
||||
static GifWidget *Instance();
|
||||
explicit GifWidget(QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
void resizeEvent(QResizeEvent *);
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
private:
|
||||
static QScopedPointer<GifWidget> self;
|
||||
QWidget *widgetTop; //标题栏
|
||||
QWidget *widgetMain; //中间部分
|
||||
QWidget *widgetBottom; //底部栏
|
||||
QLineEdit *txtFps; //帧率输入框
|
||||
QLineEdit *txtWidth; //宽度输入框
|
||||
QLineEdit *txtHeight; //高度输入框
|
||||
QPushButton *btnStart; //开始按钮
|
||||
QLabel *labStatus; //显示状态信息
|
||||
|
||||
int fps; //帧数 100为1s
|
||||
int borderWidth; //边框宽度
|
||||
QColor bgColor; //背景颜色
|
||||
|
||||
int count; //帧数计数
|
||||
QString fileName; //保存文件名称
|
||||
QRect rectGif; //截屏区域
|
||||
QTimer *timer; //截屏定时器
|
||||
|
||||
Gif gif; //gif类对象
|
||||
Gif::GifWriter *gifWriter; //gif写入对象
|
||||
|
||||
public:
|
||||
int getBorderWidth() const;
|
||||
QColor getBgColor() const;
|
||||
|
||||
private slots:
|
||||
void initControl();
|
||||
void initForm();
|
||||
void saveImage();
|
||||
void record();
|
||||
void closeAll();
|
||||
void resizeForm();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setBorderWidth(int borderWidth);
|
||||
void setBgColor(const QColor &bgColor);
|
||||
};
|
||||
|
||||
#endif // GIFWIDGET_H
|
||||
20
gifwidget/gifwidget.pro
Normal file
20
gifwidget/gifwidget.pro
Normal file
@@ -0,0 +1,20 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2017-01-05T22:11:54
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = gifwidget
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += gifwidget.cpp
|
||||
HEADERS += gifwidget.h
|
||||
HEADERS += gif.h
|
||||
RESOURCES += main.qrc
|
||||
BIN
gifwidget/image/gifwidget.ico
Normal file
BIN
gifwidget/image/gifwidget.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
gifwidget/image/gifwidget.png
Normal file
BIN
gifwidget/image/gifwidget.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
31
gifwidget/main.cpp
Normal file
31
gifwidget/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "gifwidget.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
#include <QIcon>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
a.setWindowIcon(QIcon(":/image/gifwidget.ico"));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
GifWidget::Instance()->show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
5
gifwidget/main.qrc
Normal file
5
gifwidget/main.qrc
Normal file
@@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>image/gifwidget.ico</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
56
lightbutton/frmlightbutton.cpp
Normal file
56
lightbutton/frmlightbutton.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmlightbutton.h"
|
||||
#include "ui_frmlightbutton.h"
|
||||
#include "qdatetime.h"
|
||||
#include "qtimer.h"
|
||||
|
||||
frmLightButton::frmLightButton(QWidget *parent) : QWidget(parent), ui(new Ui::frmLightButton)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
}
|
||||
|
||||
frmLightButton::~frmLightButton()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmLightButton::initForm()
|
||||
{
|
||||
ui->lightButton2->setBgColor(QColor(255, 107, 107));
|
||||
ui->lightButton3->setBgColor(QColor(24, 189, 155));
|
||||
|
||||
type = 0;
|
||||
|
||||
QTimer *timer = new QTimer(this);
|
||||
timer->setInterval(1000);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateValue()));
|
||||
timer->start();
|
||||
updateValue();
|
||||
|
||||
//以下方法启动报警
|
||||
//ui->lightButton1->setAlarmColor(QColor(255, 0, 0));
|
||||
//ui->lightButton1->setNormalColor(QColor(0, 0, 0));
|
||||
//ui->lightButton1->startAlarm();
|
||||
}
|
||||
|
||||
void frmLightButton::updateValue()
|
||||
{
|
||||
if (type == 0) {
|
||||
ui->lightButton1->setLightGreen();
|
||||
ui->lightButton2->setLightRed();
|
||||
ui->lightButton3->setLightBlue();
|
||||
type = 1;
|
||||
} else if (type == 1) {
|
||||
ui->lightButton1->setLightBlue();
|
||||
ui->lightButton2->setLightGreen();
|
||||
ui->lightButton3->setLightRed();
|
||||
type = 2;
|
||||
} else if (type == 2) {
|
||||
ui->lightButton1->setLightRed();
|
||||
ui->lightButton2->setLightBlue();
|
||||
ui->lightButton3->setLightGreen();
|
||||
type = 0;
|
||||
}
|
||||
}
|
||||
28
lightbutton/frmlightbutton.h
Normal file
28
lightbutton/frmlightbutton.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef FRMLIGHTBUTTON_H
|
||||
#define FRMLIGHTBUTTON_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class frmLightButton;
|
||||
}
|
||||
|
||||
class frmLightButton : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmLightButton(QWidget *parent = 0);
|
||||
~frmLightButton();
|
||||
|
||||
private:
|
||||
Ui::frmLightButton *ui;
|
||||
int type;
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
void updateValue();
|
||||
};
|
||||
|
||||
#endif // FRMLIGHTBUTTON_H
|
||||
38
lightbutton/frmlightbutton.ui
Normal file
38
lightbutton/frmlightbutton.ui
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmLightButton</class>
|
||||
<widget class="QWidget" name="frmLightButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="LightButton" name="lightButton1"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LightButton" name="lightButton2"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LightButton" name="lightButton3"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LightButton</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>lightbutton.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
449
lightbutton/lightbutton.cpp
Normal file
449
lightbutton/lightbutton.cpp
Normal file
@@ -0,0 +1,449 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "lightbutton.h"
|
||||
#include "qpainter.h"
|
||||
#include "qevent.h"
|
||||
#include "qtimer.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
LightButton::LightButton(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
text = "";
|
||||
textColor = QColor(255, 255, 255);
|
||||
alarmColor = QColor(255, 107, 107);
|
||||
normalColor = QColor(10, 10, 10);
|
||||
|
||||
borderOutColorStart = QColor(255, 255, 255);
|
||||
borderOutColorEnd = QColor(166, 166, 166);
|
||||
|
||||
borderInColorStart = QColor(166, 166, 166);
|
||||
borderInColorEnd = QColor(255, 255, 255);
|
||||
|
||||
bgColor = QColor(100, 184, 255);
|
||||
|
||||
showRect = false;
|
||||
showOverlay = true;
|
||||
overlayColor = QColor(255, 255, 255);
|
||||
|
||||
canMove = false;
|
||||
this->installEventFilter(this);
|
||||
|
||||
timerAlarm = new QTimer(this);
|
||||
connect(timerAlarm, SIGNAL(timeout()), this, SLOT(alarm()));
|
||||
timerAlarm->setInterval(500);
|
||||
|
||||
//setFont(QFont("Arial", 8));
|
||||
}
|
||||
|
||||
bool LightButton::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (canMove) {
|
||||
static QPoint lastPoint;
|
||||
static bool pressed = false;
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
|
||||
if (mouseEvent->type() == QEvent::MouseButtonPress) {
|
||||
if (this->rect().contains(mouseEvent->pos()) && (mouseEvent->button() == Qt::LeftButton)) {
|
||||
lastPoint = mouseEvent->pos();
|
||||
pressed = true;
|
||||
}
|
||||
} else if (mouseEvent->type() == QEvent::MouseMove && pressed) {
|
||||
int dx = mouseEvent->pos().x() - lastPoint.x();
|
||||
int dy = mouseEvent->pos().y() - lastPoint.y();
|
||||
this->move(this->x() + dx, this->y() + dy);
|
||||
} else if (mouseEvent->type() == QEvent::MouseButtonRelease && pressed) {
|
||||
pressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void LightButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
int width = this->width();
|
||||
int height = this->height();
|
||||
int side = qMin(width, height);
|
||||
|
||||
//绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
|
||||
QPainter painter(this);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
|
||||
|
||||
if (showRect) {
|
||||
//绘制矩形区域
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(bgColor);
|
||||
painter.drawRoundedRect(this->rect(), 5, 5);
|
||||
|
||||
//绘制文字
|
||||
if (!text.isEmpty()) {
|
||||
QFont font;
|
||||
font.setPixelSize(side - 20);
|
||||
painter.setFont(font);
|
||||
painter.setPen(textColor);
|
||||
painter.drawText(this->rect(), Qt::AlignCenter, text);
|
||||
}
|
||||
} else {
|
||||
painter.translate(width / 2, height / 2);
|
||||
painter.scale(side / 200.0, side / 200.0);
|
||||
|
||||
//绘制外边框
|
||||
drawBorderOut(&painter);
|
||||
//绘制内边框
|
||||
drawBorderIn(&painter);
|
||||
//绘制内部指示颜色
|
||||
drawBg(&painter);
|
||||
//绘制居中文字
|
||||
drawText(&painter);
|
||||
//绘制遮罩层
|
||||
drawOverlay(&painter);
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::drawBorderOut(QPainter *painter)
|
||||
{
|
||||
int radius = 99;
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
QLinearGradient borderGradient(0, -radius, 0, radius);
|
||||
borderGradient.setColorAt(0, borderOutColorStart);
|
||||
borderGradient.setColorAt(1, borderOutColorEnd);
|
||||
painter->setBrush(borderGradient);
|
||||
painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void LightButton::drawBorderIn(QPainter *painter)
|
||||
{
|
||||
int radius = 90;
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
QLinearGradient borderGradient(0, -radius, 0, radius);
|
||||
borderGradient.setColorAt(0, borderInColorStart);
|
||||
borderGradient.setColorAt(1, borderInColorEnd);
|
||||
painter->setBrush(borderGradient);
|
||||
painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void LightButton::drawBg(QPainter *painter)
|
||||
{
|
||||
int radius = 80;
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(bgColor);
|
||||
painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void LightButton::drawText(QPainter *painter)
|
||||
{
|
||||
if (text.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int radius = 100;
|
||||
painter->save();
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(85);
|
||||
painter->setFont(font);
|
||||
painter->setPen(textColor);
|
||||
QRect rect(-radius, -radius, radius * 2, radius * 2);
|
||||
painter->drawText(rect, Qt::AlignCenter, text);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void LightButton::drawOverlay(QPainter *painter)
|
||||
{
|
||||
if (!showOverlay) {
|
||||
return;
|
||||
}
|
||||
|
||||
int radius = 80;
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
|
||||
QPainterPath smallCircle;
|
||||
QPainterPath bigCircle;
|
||||
radius -= 1;
|
||||
smallCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
|
||||
radius *= 2;
|
||||
bigCircle.addEllipse(-radius, -radius + 140, radius * 2, radius * 2);
|
||||
|
||||
//高光的形状为小圆扣掉大圆的部分
|
||||
QPainterPath highlight = smallCircle - bigCircle;
|
||||
|
||||
QLinearGradient linearGradient(0, -radius / 2, 0, 0);
|
||||
overlayColor.setAlpha(100);
|
||||
linearGradient.setColorAt(0.0, overlayColor);
|
||||
overlayColor.setAlpha(30);
|
||||
linearGradient.setColorAt(1.0, overlayColor);
|
||||
painter->setBrush(linearGradient);
|
||||
painter->rotate(-20);
|
||||
painter->drawPath(highlight);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QString LightButton::getText() const
|
||||
{
|
||||
return this->text;
|
||||
}
|
||||
|
||||
QColor LightButton::getTextColor() const
|
||||
{
|
||||
return this->textColor;
|
||||
}
|
||||
|
||||
QColor LightButton::getAlarmColor() const
|
||||
{
|
||||
return this->alarmColor;
|
||||
}
|
||||
|
||||
QColor LightButton::getNormalColor() const
|
||||
{
|
||||
return this->normalColor;
|
||||
}
|
||||
|
||||
QColor LightButton::getBorderOutColorStart() const
|
||||
{
|
||||
return this->borderOutColorStart;
|
||||
}
|
||||
|
||||
QColor LightButton::getBorderOutColorEnd() const
|
||||
{
|
||||
return this->borderOutColorEnd;
|
||||
}
|
||||
|
||||
QColor LightButton::getBorderInColorStart() const
|
||||
{
|
||||
return this->borderInColorStart;
|
||||
}
|
||||
|
||||
QColor LightButton::getBorderInColorEnd() const
|
||||
{
|
||||
return this->borderInColorEnd;
|
||||
}
|
||||
|
||||
QColor LightButton::getBgColor() const
|
||||
{
|
||||
return this->bgColor;
|
||||
}
|
||||
|
||||
bool LightButton::getCanMove() const
|
||||
{
|
||||
return this->canMove;
|
||||
}
|
||||
|
||||
bool LightButton::getShowRect() const
|
||||
{
|
||||
return this->showRect;
|
||||
}
|
||||
|
||||
bool LightButton::getShowOverlay() const
|
||||
{
|
||||
return this->showOverlay;
|
||||
}
|
||||
|
||||
QColor LightButton::getOverlayColor() const
|
||||
{
|
||||
return this->overlayColor;
|
||||
}
|
||||
|
||||
QSize LightButton::sizeHint() const
|
||||
{
|
||||
return QSize(100, 100);
|
||||
}
|
||||
|
||||
QSize LightButton::minimumSizeHint() const
|
||||
{
|
||||
return QSize(10, 10);
|
||||
}
|
||||
|
||||
void LightButton::setText(const QString &text)
|
||||
{
|
||||
if (this->text != text) {
|
||||
this->text = text;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setTextColor(const QColor &textColor)
|
||||
{
|
||||
if (this->textColor != textColor) {
|
||||
this->textColor = textColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setAlarmColor(const QColor &alarmColor)
|
||||
{
|
||||
if (this->alarmColor != alarmColor) {
|
||||
this->alarmColor = alarmColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setNormalColor(const QColor &normalColor)
|
||||
{
|
||||
if (this->normalColor != normalColor) {
|
||||
this->normalColor = normalColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setBorderOutColorStart(const QColor &borderOutColorStart)
|
||||
{
|
||||
if (this->borderOutColorStart != borderOutColorStart) {
|
||||
this->borderOutColorStart = borderOutColorStart;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setBorderOutColorEnd(const QColor &borderOutColorEnd)
|
||||
{
|
||||
if (this->borderOutColorEnd != borderOutColorEnd) {
|
||||
this->borderOutColorEnd = borderOutColorEnd;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setBorderInColorStart(const QColor &borderInColorStart)
|
||||
{
|
||||
if (this->borderInColorStart != borderInColorStart) {
|
||||
this->borderInColorStart = borderInColorStart;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setBorderInColorEnd(const QColor &borderInColorEnd)
|
||||
{
|
||||
if (this->borderInColorEnd != borderInColorEnd) {
|
||||
this->borderInColorEnd = borderInColorEnd;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setBgColor(const QColor &bgColor)
|
||||
{
|
||||
if (this->bgColor != bgColor) {
|
||||
this->bgColor = bgColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setCanMove(bool canMove)
|
||||
{
|
||||
if (this->canMove != canMove) {
|
||||
this->canMove = canMove;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setShowRect(bool showRect)
|
||||
{
|
||||
if (this->showRect != showRect) {
|
||||
this->showRect = showRect;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setShowOverlay(bool showOverlay)
|
||||
{
|
||||
if (this->showOverlay != showOverlay) {
|
||||
this->showOverlay = showOverlay;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setOverlayColor(const QColor &overlayColor)
|
||||
{
|
||||
if (this->overlayColor != overlayColor) {
|
||||
this->overlayColor = overlayColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::setGreen()
|
||||
{
|
||||
textColor = QColor(255, 255, 255);
|
||||
setBgColor(QColor(0, 166, 0));
|
||||
}
|
||||
|
||||
void LightButton::setRed()
|
||||
{
|
||||
textColor = QColor(255, 255, 255);
|
||||
setBgColor(QColor(255, 0, 0));
|
||||
}
|
||||
|
||||
void LightButton::setYellow()
|
||||
{
|
||||
textColor = QColor(25, 50, 7);
|
||||
setBgColor(QColor(238, 238, 0));
|
||||
}
|
||||
|
||||
void LightButton::setBlack()
|
||||
{
|
||||
textColor = QColor(255, 255, 255);
|
||||
setBgColor(QColor(10, 10, 10));
|
||||
}
|
||||
|
||||
void LightButton::setGray()
|
||||
{
|
||||
textColor = QColor(255, 255, 255);
|
||||
setBgColor(QColor(129, 129, 129));
|
||||
}
|
||||
|
||||
void LightButton::setBlue()
|
||||
{
|
||||
textColor = QColor(255, 255, 255);
|
||||
setBgColor(QColor(0, 0, 166));
|
||||
}
|
||||
|
||||
void LightButton::setLightBlue()
|
||||
{
|
||||
textColor = QColor(255, 255, 255);
|
||||
setBgColor(QColor(100, 184, 255));
|
||||
}
|
||||
|
||||
void LightButton::setLightRed()
|
||||
{
|
||||
textColor = QColor(255, 255, 255);
|
||||
setBgColor(QColor(255, 107, 107));
|
||||
}
|
||||
|
||||
void LightButton::setLightGreen()
|
||||
{
|
||||
textColor = QColor(255, 255, 255);
|
||||
setBgColor(QColor(24, 189, 155));
|
||||
}
|
||||
|
||||
void LightButton::startAlarm()
|
||||
{
|
||||
if (!timerAlarm->isActive()) {
|
||||
timerAlarm->start();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::stopAlarm()
|
||||
{
|
||||
if (timerAlarm->isActive()) {
|
||||
timerAlarm->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void LightButton::alarm()
|
||||
{
|
||||
static bool isAlarm = false;
|
||||
if (isAlarm) {
|
||||
textColor = QColor(255, 255, 255);
|
||||
bgColor = normalColor;
|
||||
} else {
|
||||
textColor = QColor(255, 255, 255);
|
||||
bgColor = alarmColor;
|
||||
}
|
||||
|
||||
this->update();
|
||||
isAlarm = !isAlarm;
|
||||
}
|
||||
BIN
lightbutton/lightbutton.gif
Normal file
BIN
lightbutton/lightbutton.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
156
lightbutton/lightbutton.h
Normal file
156
lightbutton/lightbutton.h
Normal file
@@ -0,0 +1,156 @@
|
||||
#ifndef LIGHTBUTTON_H
|
||||
#define LIGHTBUTTON_H
|
||||
|
||||
/**
|
||||
* 高亮发光按钮控件 作者:feiyangqingyun(QQ:517216493) 2016-10-16
|
||||
* 1:可设置文本,居中显示
|
||||
* 2:可设置文本颜色
|
||||
* 3:可设置外边框渐变颜色
|
||||
* 4:可设置里边框渐变颜色
|
||||
* 5:可设置背景色
|
||||
* 6:可直接调用内置的设置 绿色/红色/黄色/黑色/蓝色 等公有槽函数
|
||||
* 7:可设置是否在容器中可移动,当成一个对象使用
|
||||
* 8:可设置是否显示矩形
|
||||
* 9:可设置报警颜色+非报警颜色
|
||||
* 10:可控制启动报警和停止报警,报警时闪烁
|
||||
*/
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#ifdef quc
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT LightButton : public QWidget
|
||||
#else
|
||||
class LightButton : public QWidget
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString text READ getText WRITE setText)
|
||||
Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)
|
||||
Q_PROPERTY(QColor alarmColor READ getAlarmColor WRITE setAlarmColor)
|
||||
Q_PROPERTY(QColor normalColor READ getNormalColor WRITE setNormalColor)
|
||||
|
||||
Q_PROPERTY(QColor borderOutColorStart READ getBorderOutColorStart WRITE setBorderOutColorStart)
|
||||
Q_PROPERTY(QColor borderOutColorEnd READ getBorderOutColorEnd WRITE setBorderOutColorEnd)
|
||||
Q_PROPERTY(QColor borderInColorStart READ getBorderInColorStart WRITE setBorderInColorStart)
|
||||
Q_PROPERTY(QColor borderInColorEnd READ getBorderInColorEnd WRITE setBorderInColorEnd)
|
||||
Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor)
|
||||
|
||||
Q_PROPERTY(bool canMove READ getCanMove WRITE setCanMove)
|
||||
Q_PROPERTY(bool showRect READ getShowRect WRITE setShowRect)
|
||||
Q_PROPERTY(bool showOverlay READ getShowOverlay WRITE setShowOverlay)
|
||||
Q_PROPERTY(QColor overlayColor READ getOverlayColor WRITE setOverlayColor)
|
||||
|
||||
public:
|
||||
explicit LightButton(QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
void paintEvent(QPaintEvent *);
|
||||
void drawBorderOut(QPainter *painter);
|
||||
void drawBorderIn(QPainter *painter);
|
||||
void drawBg(QPainter *painter);
|
||||
void drawText(QPainter *painter);
|
||||
void drawOverlay(QPainter *painter);
|
||||
|
||||
private:
|
||||
QString text; //文本
|
||||
QColor textColor; //文字颜色
|
||||
QColor alarmColor; //报警颜色
|
||||
QColor normalColor; //正常颜色
|
||||
|
||||
QColor borderOutColorStart; //外边框渐变开始颜色
|
||||
QColor borderOutColorEnd; //外边框渐变结束颜色
|
||||
QColor borderInColorStart; //里边框渐变开始颜色
|
||||
QColor borderInColorEnd; //里边框渐变结束颜色
|
||||
QColor bgColor; //背景颜色
|
||||
|
||||
bool showRect; //显示成矩形
|
||||
bool canMove; //是否能够移动
|
||||
bool showOverlay; //是否显示遮罩层
|
||||
QColor overlayColor; //遮罩层颜色
|
||||
|
||||
QTimer *timerAlarm; //定时器切换颜色
|
||||
|
||||
public:
|
||||
QString getText() const;
|
||||
QColor getTextColor() const;
|
||||
QColor getAlarmColor() const;
|
||||
QColor getNormalColor() const;
|
||||
|
||||
QColor getBorderOutColorStart() const;
|
||||
QColor getBorderOutColorEnd() const;
|
||||
QColor getBorderInColorStart() const;
|
||||
QColor getBorderInColorEnd() const;
|
||||
QColor getBgColor() const;
|
||||
|
||||
bool getCanMove() const;
|
||||
bool getShowRect() const;
|
||||
bool getShowOverlay() const;
|
||||
QColor getOverlayColor() const;
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置文本
|
||||
void setText(const QString &text);
|
||||
//设置文本颜色
|
||||
void setTextColor(const QColor &textColor);
|
||||
|
||||
//设置报警颜色+正常颜色
|
||||
void setAlarmColor(const QColor &alarmColor);
|
||||
void setNormalColor(const QColor &normalColor);
|
||||
|
||||
//设置外边框渐变颜色
|
||||
void setBorderOutColorStart(const QColor &borderOutColorStart);
|
||||
void setBorderOutColorEnd(const QColor &borderOutColorEnd);
|
||||
|
||||
//设置里边框渐变颜色
|
||||
void setBorderInColorStart(const QColor &borderInColorStart);
|
||||
void setBorderInColorEnd(const QColor &borderInColorEnd);
|
||||
|
||||
//设置背景色
|
||||
void setBgColor(const QColor &bgColor);
|
||||
|
||||
//设置是否可移动
|
||||
void setCanMove(bool canMove);
|
||||
//设置是否显示矩形
|
||||
void setShowRect(bool showRect);
|
||||
//设置是否显示遮罩层
|
||||
void setShowOverlay(bool showOverlay);
|
||||
//设置遮罩层颜色
|
||||
void setOverlayColor(const QColor &overlayColor);
|
||||
|
||||
//设置为绿色
|
||||
void setGreen();
|
||||
//设置为红色
|
||||
void setRed();
|
||||
//设置为黄色
|
||||
void setYellow();
|
||||
//设置为黑色
|
||||
void setBlack();
|
||||
//设置为灰色
|
||||
void setGray();
|
||||
//设置为蓝色
|
||||
void setBlue();
|
||||
//设置为淡蓝色
|
||||
void setLightBlue();
|
||||
//设置为淡红色
|
||||
void setLightRed();
|
||||
//设置为淡绿色
|
||||
void setLightGreen();
|
||||
|
||||
//设置报警闪烁
|
||||
void startAlarm();
|
||||
void stopAlarm();
|
||||
void alarm();
|
||||
};
|
||||
|
||||
#endif // LIGHTBUTTON_H
|
||||
23
lightbutton/lightbutton.pro
Normal file
23
lightbutton/lightbutton.pro
Normal file
@@ -0,0 +1,23 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2017-02-08T15:04:18
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = lightbutton
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmlightbutton.cpp
|
||||
SOURCES += lightbutton.cpp
|
||||
|
||||
HEADERS += frmlightbutton.h
|
||||
HEADERS += lightbutton.h
|
||||
|
||||
FORMS += frmlightbutton.ui
|
||||
31
lightbutton/main.cpp
Normal file
31
lightbutton/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmlightbutton.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmLightButton w;
|
||||
w.setWindowTitle("高亮发光按钮");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
41
movewidget/frmmovewidget.cpp
Normal file
41
movewidget/frmmovewidget.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmmovewidget.h"
|
||||
#include "ui_frmmovewidget.h"
|
||||
#include "qpushbutton.h"
|
||||
#include "qprogressbar.h"
|
||||
#include "movewidget.h"
|
||||
|
||||
frmMoveWidget::frmMoveWidget(QWidget *parent) : QWidget(parent), ui(new Ui::frmMoveWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
}
|
||||
|
||||
frmMoveWidget::~frmMoveWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmMoveWidget::initForm()
|
||||
{
|
||||
QPushButton *btn1 = new QPushButton(this);
|
||||
btn1->setGeometry(10, 10, 250, 25);
|
||||
btn1->setText("按住我拖动(仅限左键拖动)");
|
||||
MoveWidget *moveWidget1 = new MoveWidget(this);
|
||||
moveWidget1->setWidget(btn1);
|
||||
|
||||
QPushButton *btn2 = new QPushButton(this);
|
||||
btn2->setGeometry(10, 40, 250, 25);
|
||||
btn2->setText("按住我拖动(支持右键拖动)");
|
||||
MoveWidget *moveWidget2 = new MoveWidget(this);
|
||||
moveWidget2->setWidget(btn2);
|
||||
moveWidget2->setLeftButton(false);
|
||||
|
||||
QProgressBar *bar = new QProgressBar(this);
|
||||
bar->setGeometry(10, 70, 250, 25);
|
||||
bar->setRange(0, 0);
|
||||
bar->setTextVisible(false);
|
||||
MoveWidget *moveWidget3 = new MoveWidget(this);
|
||||
moveWidget3->setWidget(bar);
|
||||
}
|
||||
26
movewidget/frmmovewidget.h
Normal file
26
movewidget/frmmovewidget.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef FRMMOVEWIDGET_H
|
||||
#define FRMMOVEWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class frmMoveWidget;
|
||||
}
|
||||
|
||||
class frmMoveWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmMoveWidget(QWidget *parent = 0);
|
||||
~frmMoveWidget();
|
||||
|
||||
private:
|
||||
Ui::frmMoveWidget *ui;
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
};
|
||||
|
||||
#endif // FRMMOVEWIDGET_H
|
||||
19
movewidget/frmmovewidget.ui
Normal file
19
movewidget/frmmovewidget.ui
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmMoveWidget</class>
|
||||
<widget class="QWidget" name="frmMoveWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
31
movewidget/main.cpp
Normal file
31
movewidget/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmmovewidget.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmMoveWidget w;
|
||||
w.setWindowTitle("通用移动类");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
74
movewidget/movewidget.cpp
Normal file
74
movewidget/movewidget.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "movewidget.h"
|
||||
#include "qevent.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
MoveWidget::MoveWidget(QObject *parent) : QObject(parent)
|
||||
{
|
||||
lastPoint = QPoint(0, 0);
|
||||
pressed = false;
|
||||
leftButton = true;
|
||||
inControl = true;
|
||||
widget = 0;
|
||||
}
|
||||
|
||||
bool MoveWidget::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (widget != 0 && watched == widget) {
|
||||
QMouseEvent *mouseEvent = (QMouseEvent *)event;
|
||||
if (mouseEvent->type() == QEvent::MouseButtonPress) {
|
||||
//如果限定了只能鼠标左键拖动则判断当前是否是鼠标左键
|
||||
if (leftButton && mouseEvent->button() != Qt::LeftButton) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//判断控件的区域是否包含了当前鼠标的坐标
|
||||
if (widget->rect().contains(mouseEvent->pos())) {
|
||||
lastPoint = mouseEvent->pos();
|
||||
pressed = true;
|
||||
}
|
||||
} else if (mouseEvent->type() == QEvent::MouseMove && pressed) {
|
||||
//计算坐标偏移值,调用move函数移动过去
|
||||
int offsetX = mouseEvent->pos().x() - lastPoint.x();
|
||||
int offsetY = mouseEvent->pos().y() - lastPoint.y();
|
||||
int x = widget->x() + offsetX;
|
||||
int y = widget->y() + offsetY;
|
||||
if (inControl) {
|
||||
//可以自行调整限定在容器中的范围,这里默认保留20个像素在里面
|
||||
int offset = 20;
|
||||
bool xyOut = (x + widget->width() < offset || y + widget->height() < offset);
|
||||
bool whOut = false;
|
||||
QWidget *w = (QWidget *)widget->parent();
|
||||
if (w != 0) {
|
||||
whOut = (w->width() - x < offset || w->height() - y < offset);
|
||||
}
|
||||
if (xyOut || whOut) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
widget->move(x, y);
|
||||
} else if (mouseEvent->type() == QEvent::MouseButtonRelease && pressed) {
|
||||
pressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void MoveWidget::setWidget(QWidget *widget)
|
||||
{
|
||||
if (this->widget == 0) {
|
||||
this->widget = widget;
|
||||
this->widget->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveWidget::setLeftButton(bool leftButton)
|
||||
{
|
||||
this->leftButton = leftButton;
|
||||
}
|
||||
|
||||
void MoveWidget::setInControl(bool inControl)
|
||||
{
|
||||
this->inControl = inControl;
|
||||
}
|
||||
49
movewidget/movewidget.h
Normal file
49
movewidget/movewidget.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef MOVEWIDGET_H
|
||||
#define MOVEWIDGET_H
|
||||
|
||||
/**
|
||||
* 通用控件移动类 作者:feiyangqingyun(QQ:517216493) 2019-9-28
|
||||
* 1:可以指定需要移动的widget
|
||||
* 2:可设置是否限定鼠标左键拖动
|
||||
* 3:支持任意widget控件
|
||||
*/
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#ifdef quc
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT MoveWidget : public QObject
|
||||
#else
|
||||
class MoveWidget : public QObject
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MoveWidget(QObject *parent = 0);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
QPoint lastPoint; //最后按下的坐标
|
||||
bool pressed; //鼠标是否按下
|
||||
bool leftButton; //限定鼠标左键
|
||||
bool inControl; //限定在容器内
|
||||
QWidget *widget; //移动的控件
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置是否限定鼠标左键
|
||||
void setLeftButton(bool leftButton);
|
||||
//设置是否限定不能移出容器外面
|
||||
void setInControl(bool inControl);
|
||||
//设置要移动的控件
|
||||
void setWidget(QWidget *widget);
|
||||
};
|
||||
|
||||
#endif // MOVEWIDGET_H
|
||||
23
movewidget/movewidget.pro
Normal file
23
movewidget/movewidget.pro
Normal file
@@ -0,0 +1,23 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2019-09-28T15:04:18
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = lightbutton
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += frmmovewidget.cpp
|
||||
SOURCES += movewidget.cpp
|
||||
|
||||
HEADERS += frmmovewidget.h
|
||||
HEADERS += movewidget.h
|
||||
|
||||
FORMS += frmmovewidget.ui
|
||||
367
navbutton/frmnavbutton.cpp
Normal file
367
navbutton/frmnavbutton.cpp
Normal file
@@ -0,0 +1,367 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmnavbutton.h"
|
||||
#include "ui_frmnavbutton.h"
|
||||
#include "navbutton.h"
|
||||
#include "iconhelper.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
frmNavButton::frmNavButton(QWidget *parent) : QWidget(parent), ui(new Ui::frmNavButton)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
}
|
||||
|
||||
frmNavButton::~frmNavButton()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmNavButton::initForm()
|
||||
{
|
||||
quint32 size = 15;
|
||||
quint32 pixWidth = 15;
|
||||
quint32 pixHeight = 15;
|
||||
|
||||
//从图形字体获得图片,也可以从资源文件或者路径文件获取
|
||||
QChar icon = 0xf061;
|
||||
QPixmap iconNormal = IconHelper::Instance()->getPixmap(QColor(100, 100, 100).name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconHover = IconHelper::Instance()->getPixmap(QColor(255, 255, 255).name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconCheck = IconHelper::Instance()->getPixmap(QColor(255, 255, 255).name(), icon, size, pixWidth, pixHeight);
|
||||
|
||||
btns1 << ui->navButton11 << ui->navButton12 << ui->navButton13 << ui->navButton14;
|
||||
for (int i = 0; i < btns1.count(); i++) {
|
||||
NavButton *btn = btns1.at(i);
|
||||
btn->setPaddingLeft(32);
|
||||
btn->setLineSpace(6);
|
||||
|
||||
btn->setShowIcon(true);
|
||||
btn->setIconSpace(15);
|
||||
btn->setIconSize(QSize(10, 10));
|
||||
btn->setIconNormal(iconNormal);
|
||||
btn->setIconHover(iconHover);
|
||||
btn->setIconCheck(iconCheck);
|
||||
|
||||
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClick1()));
|
||||
}
|
||||
|
||||
size = 15;
|
||||
pixWidth = 20;
|
||||
pixHeight = 20;
|
||||
|
||||
QList<QChar> pixChar;
|
||||
pixChar << 0xf17b << 0xf002 << 0xf013 << 0xf021 << 0xf0e0 << 0xf135;
|
||||
QColor normalBgColor = QColor("#2D9191");
|
||||
QColor hoverBgColor = QColor("#187294");
|
||||
QColor checkBgColor = QColor("#145C75");
|
||||
QColor normalTextColor = QColor("#FFFFFF");
|
||||
QColor hoverTextColor = QColor("#FFFFFF");
|
||||
QColor checkTextColor = QColor("#FFFFFF");
|
||||
|
||||
btns2 << ui->navButton21 << ui->navButton22 << ui->navButton23 << ui->navButton24;
|
||||
for (int i = 0; i < btns2.count(); i++) {
|
||||
NavButton *btn = btns2.at(i);
|
||||
btn->setPaddingLeft(35);
|
||||
btn->setLineSpace(0);
|
||||
btn->setLineWidth(8);
|
||||
btn->setLineColor(QColor(255, 107, 107));
|
||||
btn->setShowTriangle(true);
|
||||
|
||||
btn->setShowIcon(true);
|
||||
btn->setIconSpace(10);
|
||||
btn->setIconSize(QSize(22, 22));
|
||||
|
||||
//分开设置图标
|
||||
QChar icon = pixChar.at(i);
|
||||
QPixmap iconNormal = IconHelper::Instance()->getPixmap(normalTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconHover = IconHelper::Instance()->getPixmap(hoverTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconCheck = IconHelper::Instance()->getPixmap(checkTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
|
||||
btn->setIconNormal(iconNormal);
|
||||
btn->setIconHover(iconHover);
|
||||
btn->setIconCheck(iconCheck);
|
||||
|
||||
btn->setNormalBgColor(normalBgColor);
|
||||
btn->setHoverBgColor(hoverBgColor);
|
||||
btn->setCheckBgColor(checkBgColor);
|
||||
btn->setNormalTextColor(normalTextColor);
|
||||
btn->setHoverTextColor(hoverTextColor);
|
||||
btn->setCheckTextColor(checkTextColor);
|
||||
|
||||
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClick2()));
|
||||
}
|
||||
|
||||
normalBgColor = QColor("#292F38");
|
||||
hoverBgColor = QColor("#1D2025");
|
||||
checkBgColor = QColor("#1D2025");
|
||||
normalTextColor = QColor("#54626F");
|
||||
hoverTextColor = QColor("#FDFDFD");
|
||||
checkTextColor = QColor("#FDFDFD");
|
||||
|
||||
btns3 << ui->navButton31 << ui->navButton32 << ui->navButton33 << ui->navButton34;
|
||||
for (int i = 0; i < btns3.count(); i++) {
|
||||
NavButton *btn = btns3.at(i);
|
||||
btn->setPaddingLeft(35);
|
||||
btn->setLineWidth(10);
|
||||
btn->setLineColor(QColor("#029FEA"));
|
||||
btn->setShowTriangle(true);
|
||||
btn->setTextAlign(NavButton::TextAlign_Left);
|
||||
btn->setTrianglePosition(NavButton::TrianglePosition_Left);
|
||||
btn->setLinePosition(NavButton::LinePosition_Right);
|
||||
|
||||
btn->setShowIcon(true);
|
||||
btn->setIconSpace(10);
|
||||
btn->setIconSize(QSize(22, 22));
|
||||
|
||||
//分开设置图标
|
||||
QChar icon = pixChar.at(i);
|
||||
QPixmap iconNormal = IconHelper::Instance()->getPixmap(normalTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconHover = IconHelper::Instance()->getPixmap(hoverTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconCheck = IconHelper::Instance()->getPixmap(checkTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
|
||||
btn->setIconNormal(iconNormal);
|
||||
btn->setIconHover(iconHover);
|
||||
btn->setIconCheck(iconCheck);
|
||||
|
||||
btn->setNormalBgColor(normalBgColor);
|
||||
btn->setHoverBgColor(hoverBgColor);
|
||||
btn->setCheckBgColor(checkBgColor);
|
||||
btn->setNormalTextColor(normalTextColor);
|
||||
btn->setHoverTextColor(hoverTextColor);
|
||||
btn->setCheckTextColor(checkTextColor);
|
||||
|
||||
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClick3()));
|
||||
}
|
||||
|
||||
size = 15;
|
||||
pixWidth = 15;
|
||||
pixHeight = 15;
|
||||
|
||||
icon = 0xf105;
|
||||
iconNormal = IconHelper::Instance()->getPixmap(QColor(100, 100, 100).name(), icon, size, pixWidth, pixHeight);
|
||||
iconHover = IconHelper::Instance()->getPixmap(QColor(255, 255, 255).name(), icon, size, pixWidth, pixHeight);
|
||||
iconCheck = IconHelper::Instance()->getPixmap(QColor(255, 255, 255).name(), icon, size, pixWidth, pixHeight);
|
||||
|
||||
btns4 << ui->navButton41 << ui->navButton42 << ui->navButton43 << ui->navButton44;
|
||||
for (int i = 0; i < btns4.count(); i++) {
|
||||
NavButton *btn = btns4.at(i);
|
||||
btn->setLineSpace(10);
|
||||
btn->setLineWidth(10);
|
||||
btn->setPaddingRight(25);
|
||||
btn->setShowTriangle(true);
|
||||
btn->setTextAlign(NavButton::TextAlign_Right);
|
||||
btn->setTrianglePosition(NavButton::TrianglePosition_Left);
|
||||
btn->setLinePosition(NavButton::LinePosition_Right);
|
||||
|
||||
btn->setShowIcon(true);
|
||||
btn->setIconSpace(25);
|
||||
btn->setIconSize(QSize(15, 15));
|
||||
btn->setIconNormal(iconNormal);
|
||||
btn->setIconHover(iconHover);
|
||||
btn->setIconCheck(iconCheck);
|
||||
|
||||
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClick4()));
|
||||
}
|
||||
|
||||
size = 15;
|
||||
pixWidth = 20;
|
||||
pixHeight = 20;
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(15);
|
||||
font.setBold(true);
|
||||
|
||||
normalBgColor = QColor("#292929");
|
||||
hoverBgColor = QColor("#064077");
|
||||
checkBgColor = QColor("#10689A");
|
||||
normalTextColor = QColor("#FFFFFF");
|
||||
hoverTextColor = Qt::yellow;
|
||||
checkTextColor = QColor("#FFFFFF");
|
||||
|
||||
btns5 << ui->navButton51 << ui->navButton52 << ui->navButton53 << ui->navButton54 << ui->navButton55;
|
||||
for (int i = 0; i < btns5.count(); i++) {
|
||||
NavButton *btn = btns5.at(i);
|
||||
btn->setFont(font);
|
||||
btn->setPaddingLeft(20);
|
||||
btn->setShowLine(false);
|
||||
btn->setTextAlign(NavButton::TextAlign_Center);
|
||||
btn->setLinePosition(NavButton::LinePosition_Bottom);
|
||||
|
||||
btn->setShowIcon(true);
|
||||
btn->setIconSpace(15);
|
||||
btn->setIconSize(QSize(22, 22));
|
||||
|
||||
//分开设置图标
|
||||
QChar icon = pixChar.at(i);
|
||||
QPixmap iconNormal = IconHelper::Instance()->getPixmap(normalTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconHover = IconHelper::Instance()->getPixmap(hoverTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconCheck = IconHelper::Instance()->getPixmap(checkTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
|
||||
btn->setIconNormal(iconNormal);
|
||||
btn->setIconHover(iconHover);
|
||||
btn->setIconCheck(iconCheck);
|
||||
|
||||
btn->setNormalBgColor(normalBgColor);
|
||||
btn->setHoverBgColor(hoverBgColor);
|
||||
btn->setCheckBgColor(checkBgColor);
|
||||
btn->setNormalTextColor(normalTextColor);
|
||||
btn->setHoverTextColor(hoverTextColor);
|
||||
btn->setCheckTextColor(checkTextColor);
|
||||
|
||||
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClick5()));
|
||||
}
|
||||
|
||||
normalBgColor = QColor("#E6393D");
|
||||
hoverBgColor = QColor("#EE0000");
|
||||
checkBgColor = QColor("#A40001");
|
||||
normalTextColor = QColor("#FFFFFF");
|
||||
hoverTextColor = QColor("#FFFFFF");
|
||||
checkTextColor = QColor("#FFFFFF");
|
||||
|
||||
btns6 << ui->navButton61 << ui->navButton62 << ui->navButton63 << ui->navButton64 << ui->navButton65;
|
||||
for (int i = 0; i < btns6.count(); i++) {
|
||||
NavButton *btn = btns6.at(i);
|
||||
btn->setFont(font);
|
||||
btn->setPaddingLeft(20);
|
||||
btn->setShowLine(false);
|
||||
btn->setTextAlign(NavButton::TextAlign_Center);
|
||||
btn->setLinePosition(NavButton::LinePosition_Bottom);
|
||||
|
||||
btn->setShowIcon(true);
|
||||
btn->setIconSpace(15);
|
||||
btn->setIconSize(QSize(22, 22));
|
||||
|
||||
//分开设置图标
|
||||
QChar icon = pixChar.at(i);
|
||||
QPixmap iconNormal = IconHelper::Instance()->getPixmap(normalTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconHover = IconHelper::Instance()->getPixmap(hoverTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
QPixmap iconCheck = IconHelper::Instance()->getPixmap(checkTextColor.name(), icon, size, pixWidth, pixHeight);
|
||||
|
||||
btn->setIconNormal(iconNormal);
|
||||
btn->setIconHover(iconHover);
|
||||
btn->setIconCheck(iconCheck);
|
||||
|
||||
btn->setNormalBgColor(normalBgColor);
|
||||
btn->setHoverBgColor(hoverBgColor);
|
||||
btn->setCheckBgColor(checkBgColor);
|
||||
btn->setNormalTextColor(normalTextColor);
|
||||
btn->setHoverTextColor(hoverTextColor);
|
||||
btn->setCheckTextColor(checkTextColor);
|
||||
|
||||
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClick6()));
|
||||
}
|
||||
|
||||
//设置背景色为画刷
|
||||
QLinearGradient normalBgBrush(0, 0, 0, ui->navButton61->height());
|
||||
normalBgBrush.setColorAt(0.0, QColor("#3985BF"));
|
||||
normalBgBrush.setColorAt(0.5, QColor("#2972A9"));
|
||||
normalBgBrush.setColorAt(1.0, QColor("#1C6496"));
|
||||
|
||||
QLinearGradient hoverBgBrush(0, 0, 0, ui->navButton61->height());
|
||||
hoverBgBrush.setColorAt(0.0, QColor("#4897D1"));
|
||||
hoverBgBrush.setColorAt(0.5, QColor("#3283BC"));
|
||||
hoverBgBrush.setColorAt(1.0, QColor("#3088C3"));
|
||||
|
||||
btns7 << ui->navButton71 << ui->navButton72 << ui->navButton73 << ui->navButton74 << ui->navButton75 << ui->navButton76;
|
||||
for (int i = 0; i < btns7.count(); i++) {
|
||||
NavButton *btn = btns7.at(i);
|
||||
btn->setFont(font);
|
||||
btn->setPaddingLeft(0);
|
||||
btn->setLineSpace(0);
|
||||
btn->setShowTriangle(true);
|
||||
btn->setTextAlign(NavButton::TextAlign_Center);
|
||||
btn->setTrianglePosition(NavButton::TrianglePosition_Bottom);
|
||||
btn->setLinePosition(NavButton::LinePosition_Top);
|
||||
|
||||
btn->setNormalTextColor(normalTextColor);
|
||||
btn->setHoverTextColor(hoverTextColor);
|
||||
btn->setCheckTextColor(checkTextColor);
|
||||
|
||||
btn->setNormalBgBrush(normalBgBrush);
|
||||
btn->setHoverBgBrush(hoverBgBrush);
|
||||
btn->setCheckBgBrush(hoverBgBrush);
|
||||
|
||||
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClick7()));
|
||||
}
|
||||
|
||||
ui->navButton11->setChecked(true);
|
||||
ui->navButton23->setChecked(true);
|
||||
ui->navButton31->setChecked(true);
|
||||
ui->navButton44->setChecked(true);
|
||||
ui->navButton53->setChecked(true);
|
||||
ui->navButton61->setChecked(true);
|
||||
ui->navButton75->setChecked(true);
|
||||
|
||||
//设置整体圆角
|
||||
ui->widgetNav5->setStyleSheet(".QWidget{background:#292929;border:1px solid #292929;border-radius:20px;}");
|
||||
}
|
||||
|
||||
void frmNavButton::buttonClick1()
|
||||
{
|
||||
NavButton *b = (NavButton *)sender();
|
||||
qDebug() << "当前按下" << b->text();
|
||||
for (int i = 0; i < btns1.count(); i++) {
|
||||
NavButton *btn = btns1.at(i);
|
||||
btn->setChecked(b == btn);
|
||||
}
|
||||
}
|
||||
|
||||
void frmNavButton::buttonClick2()
|
||||
{
|
||||
NavButton *b = (NavButton *)sender();
|
||||
qDebug() << "当前按下" << b->text();
|
||||
for (int i = 0; i < btns2.count(); i++) {
|
||||
NavButton *btn = btns2.at(i);
|
||||
btn->setChecked(b == btn);
|
||||
}
|
||||
}
|
||||
|
||||
void frmNavButton::buttonClick3()
|
||||
{
|
||||
NavButton *b = (NavButton *)sender();
|
||||
qDebug() << "当前按下" << b->text();
|
||||
for (int i = 0; i < btns3.count(); i++) {
|
||||
NavButton *btn = btns3.at(i);
|
||||
btn->setChecked(b == btn);
|
||||
}
|
||||
}
|
||||
|
||||
void frmNavButton::buttonClick4()
|
||||
{
|
||||
NavButton *b = (NavButton *)sender();
|
||||
qDebug() << "当前按下" << b->text();
|
||||
for (int i = 0; i < btns4.count(); i++) {
|
||||
NavButton *btn = btns4.at(i);
|
||||
btn->setChecked(b == btn);
|
||||
}
|
||||
}
|
||||
|
||||
void frmNavButton::buttonClick5()
|
||||
{
|
||||
NavButton *b = (NavButton *)sender();
|
||||
qDebug() << "当前按下" << b->text();
|
||||
for (int i = 0; i < btns5.count(); i++) {
|
||||
NavButton *btn = btns5.at(i);
|
||||
btn->setChecked(b == btn);
|
||||
}
|
||||
}
|
||||
|
||||
void frmNavButton::buttonClick6()
|
||||
{
|
||||
NavButton *b = (NavButton *)sender();
|
||||
qDebug() << "当前按下" << b->text();
|
||||
for (int i = 0; i < btns6.count(); i++) {
|
||||
NavButton *btn = btns6.at(i);
|
||||
btn->setChecked(b == btn);
|
||||
}
|
||||
}
|
||||
|
||||
void frmNavButton::buttonClick7()
|
||||
{
|
||||
NavButton *b = (NavButton *)sender();
|
||||
qDebug() << "当前按下" << b->text();
|
||||
for (int i = 0; i < btns7.count(); i++) {
|
||||
NavButton *btn = btns7.at(i);
|
||||
btn->setChecked(b == btn);
|
||||
}
|
||||
}
|
||||
42
navbutton/frmnavbutton.h
Normal file
42
navbutton/frmnavbutton.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef FRMNAVBUTTON_H
|
||||
#define FRMNAVBUTTON_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class NavButton;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class frmNavButton;
|
||||
}
|
||||
|
||||
class frmNavButton : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmNavButton(QWidget *parent = 0);
|
||||
~frmNavButton();
|
||||
|
||||
private:
|
||||
Ui::frmNavButton *ui;
|
||||
QList<NavButton *> btns1;
|
||||
QList<NavButton *> btns2;
|
||||
QList<NavButton *> btns3;
|
||||
QList<NavButton *> btns4;
|
||||
QList<NavButton *> btns5;
|
||||
QList<NavButton *> btns6;
|
||||
QList<NavButton *> btns7;
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
void buttonClick1();
|
||||
void buttonClick2();
|
||||
void buttonClick3();
|
||||
void buttonClick4();
|
||||
void buttonClick5();
|
||||
void buttonClick6();
|
||||
void buttonClick7();
|
||||
};
|
||||
|
||||
#endif // FRMNAVBUTTON_H
|
||||
547
navbutton/frmnavbutton.ui
Normal file
547
navbutton/frmnavbutton.ui
Normal file
@@ -0,0 +1,547 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmNavButton</class>
|
||||
<widget class="QWidget" name="frmNavButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0" colspan="4">
|
||||
<widget class="QWidget" name="widgetNav7" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</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="NavButton" name="navButton71">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>首页</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton72">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>论坛</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton73">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Qt下载</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton74">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>作品展</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton75">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>群组</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton76">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>个人中心</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QWidget" name="widgetNav1" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<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="NavButton" name="navButton11">
|
||||
<property name="text">
|
||||
<string>学生管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton12">
|
||||
<property name="text">
|
||||
<string>教师管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton13">
|
||||
<property name="text">
|
||||
<string>成绩管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton14">
|
||||
<property name="text">
|
||||
<string>记录查询</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QWidget" name="widgetNav2" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<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="NavButton" name="navButton21">
|
||||
<property name="text">
|
||||
<string>访客登记</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton22">
|
||||
<property name="text">
|
||||
<string>记录查询</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton23">
|
||||
<property name="text">
|
||||
<string>系统设置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton24">
|
||||
<property name="text">
|
||||
<string>系统重启</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<widget class="QWidget" name="widgetNav5" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</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="NavButton" name="navButton51">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>首页</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton52">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>论坛</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton53">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>作品</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton54">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>群组</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton55">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>帮助</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QWidget" name="widgetNav6" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</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="NavButton" name="navButton61">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>首页</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton62">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>论坛</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton63">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>作品</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton64">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>群组</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton65">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>帮助</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QWidget" name="widgetNav3" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>6</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="NavButton" name="navButton31">
|
||||
<property name="text">
|
||||
<string>学生管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton32">
|
||||
<property name="text">
|
||||
<string>教师管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton33">
|
||||
<property name="text">
|
||||
<string>成绩管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton34">
|
||||
<property name="text">
|
||||
<string>记录查询</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QWidget" name="widgetNav4" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<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="NavButton" name="navButton41">
|
||||
<property name="text">
|
||||
<string>学生管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton42">
|
||||
<property name="text">
|
||||
<string>教师管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton43">
|
||||
<property name="text">
|
||||
<string>成绩管理</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="NavButton" name="navButton44">
|
||||
<property name="text">
|
||||
<string>记录查询</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="4">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>NavButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>navbutton.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
240
navbutton/iconhelper.cpp
Normal file
240
navbutton/iconhelper.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
#include "iconhelper.h"
|
||||
|
||||
QScopedPointer<IconHelper> IconHelper::self;
|
||||
IconHelper *IconHelper::Instance()
|
||||
{
|
||||
if (self.isNull()) {
|
||||
static QMutex mutex;
|
||||
QMutexLocker locker(&mutex);
|
||||
if (self.isNull()) {
|
||||
self.reset(new IconHelper);
|
||||
}
|
||||
}
|
||||
|
||||
return self.data();
|
||||
}
|
||||
|
||||
IconHelper::IconHelper(QObject *parent) : QObject(parent)
|
||||
{
|
||||
//判断图形字体是否存在,不存在则加入
|
||||
QFontDatabase fontDb;
|
||||
if (!fontDb.families().contains("FontAwesome")) {
|
||||
int fontId = fontDb.addApplicationFont(":/image/fontawesome-webfont.ttf");
|
||||
QStringList fontName = fontDb.applicationFontFamilies(fontId);
|
||||
if (fontName.count() == 0) {
|
||||
qDebug() << "load fontawesome-webfont.ttf error";
|
||||
}
|
||||
}
|
||||
|
||||
if (fontDb.families().contains("FontAwesome")) {
|
||||
iconFont = QFont("FontAwesome");
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(4,8,0))
|
||||
iconFont.setHintingPreference(QFont::PreferNoHinting);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void IconHelper::setIcon(QLabel *lab, const QChar &str, quint32 size)
|
||||
{
|
||||
iconFont.setPixelSize(size);
|
||||
lab->setFont(iconFont);
|
||||
lab->setText(str);
|
||||
}
|
||||
|
||||
void IconHelper::setIcon(QAbstractButton *btn, const QChar &str, quint32 size)
|
||||
{
|
||||
iconFont.setPixelSize(size);
|
||||
btn->setFont(iconFont);
|
||||
btn->setText(str);
|
||||
}
|
||||
|
||||
QPixmap IconHelper::getPixmap(const QColor &color, const QChar &str, quint32 size,
|
||||
quint32 pixWidth, quint32 pixHeight, int flags)
|
||||
{
|
||||
QPixmap pix(pixWidth, pixHeight);
|
||||
pix.fill(Qt::transparent);
|
||||
|
||||
QPainter painter;
|
||||
painter.begin(&pix);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
|
||||
painter.setPen(color);
|
||||
|
||||
iconFont.setPixelSize(size);
|
||||
painter.setFont(iconFont);
|
||||
painter.drawText(pix.rect(), flags, str);
|
||||
painter.end();
|
||||
|
||||
return pix;
|
||||
}
|
||||
|
||||
QPixmap IconHelper::getPixmap(QToolButton *btn, bool normal)
|
||||
{
|
||||
QPixmap pix;
|
||||
int index = btns.indexOf(btn);
|
||||
|
||||
if (index >= 0) {
|
||||
if (normal) {
|
||||
pix = pixNormal.at(index);
|
||||
} else {
|
||||
pix = pixDark.at(index);
|
||||
}
|
||||
}
|
||||
|
||||
return pix;
|
||||
}
|
||||
|
||||
void IconHelper::setStyle(QWidget *widget, const QString &type, int borderWidth, const QString &borderColor,
|
||||
const QString &normalBgColor, const QString &darkBgColor,
|
||||
const QString &normalTextColor, const QString &darkTextColor)
|
||||
{
|
||||
QString strBorder;
|
||||
if (type == "top") {
|
||||
strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;")
|
||||
.arg(borderWidth).arg(borderWidth * 2);
|
||||
} else if (type == "right") {
|
||||
strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;")
|
||||
.arg(borderWidth).arg(borderWidth * 2);
|
||||
} else if (type == "bottom") {
|
||||
strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;")
|
||||
.arg(borderWidth).arg(borderWidth * 2);
|
||||
} else if (type == "left") {
|
||||
strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;")
|
||||
.arg(borderWidth).arg(borderWidth * 2);
|
||||
}
|
||||
|
||||
QStringList qss;
|
||||
qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}")
|
||||
.arg(type).arg(normalTextColor).arg(normalBgColor));
|
||||
|
||||
qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover,"
|
||||
"QWidget[flag=\"%1\"] QAbstractButton:pressed,"
|
||||
"QWidget[flag=\"%1\"] QAbstractButton:checked{"
|
||||
"border-style:solid;%2border-color:%3;color:%4;background:%5;}")
|
||||
.arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor));
|
||||
|
||||
widget->setStyleSheet(qss.join(""));
|
||||
}
|
||||
|
||||
void IconHelper::setStyle(QWidget *widget, QList<QToolButton *> btns, QList<int> pixChar,
|
||||
quint32 iconSize, quint32 iconWidth, quint32 iconHeight,
|
||||
const QString &type, int borderWidth, const QString &borderColor,
|
||||
const QString &normalBgColor, const QString &darkBgColor,
|
||||
const QString &normalTextColor, const QString &darkTextColor)
|
||||
{
|
||||
int btnCount = btns.count();
|
||||
int charCount = pixChar.count();
|
||||
if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString strBorder;
|
||||
if (type == "top") {
|
||||
strBorder = QString("border-width:%1px 0px 0px 0px;padding:%1px %2px %2px %2px;")
|
||||
.arg(borderWidth).arg(borderWidth * 2);
|
||||
} else if (type == "right") {
|
||||
strBorder = QString("border-width:0px %1px 0px 0px;padding:%2px %1px %2px %2px;")
|
||||
.arg(borderWidth).arg(borderWidth * 2);
|
||||
} else if (type == "bottom") {
|
||||
strBorder = QString("border-width:0px 0px %1px 0px;padding:%2px %2px %1px %2px;")
|
||||
.arg(borderWidth).arg(borderWidth * 2);
|
||||
} else if (type == "left") {
|
||||
strBorder = QString("border-width:0px 0px 0px %1px;padding:%2px %2px %2px %1px;")
|
||||
.arg(borderWidth).arg(borderWidth * 2);
|
||||
}
|
||||
|
||||
//如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色
|
||||
QStringList qss;
|
||||
if (btns.at(0)->toolButtonStyle() == Qt::ToolButtonTextBesideIcon) {
|
||||
qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}")
|
||||
.arg(type).arg(strBorder).arg(normalBgColor).arg(normalTextColor).arg(normalBgColor));
|
||||
} else {
|
||||
qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}")
|
||||
.arg(type).arg(normalTextColor).arg(normalBgColor));
|
||||
}
|
||||
|
||||
qss.append(QString("QWidget[flag=\"%1\"] QAbstractButton:hover,"
|
||||
"QWidget[flag=\"%1\"] QAbstractButton:pressed,"
|
||||
"QWidget[flag=\"%1\"] QAbstractButton:checked{"
|
||||
"border-style:solid;%2border-color:%3;color:%4;background:%5;}")
|
||||
.arg(type).arg(strBorder).arg(borderColor).arg(darkTextColor).arg(darkBgColor));
|
||||
|
||||
qss.append(QString("QWidget#%1{background:%2;}").arg(widget->objectName()).arg(normalBgColor));
|
||||
|
||||
qss.append(QString("QWidget>QToolButton{border-width:0px;}"));
|
||||
qss.append(QString("QWidget>QToolButton{background-color:%1;color:%2;}")
|
||||
.arg(normalBgColor).arg(normalTextColor));
|
||||
qss.append(QString("QWidget>QToolButton:hover,QWidget>QToolButton:pressed,QWidget>QToolButton:checked{background-color:%1;color:%2;}")
|
||||
.arg(darkBgColor).arg(darkTextColor));
|
||||
|
||||
widget->setStyleSheet(qss.join(""));
|
||||
|
||||
for (int i = 0; i < btnCount; i++) {
|
||||
//存储对应按钮对象,方便鼠标移上去的时候切换图片
|
||||
QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight);
|
||||
QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight);
|
||||
|
||||
btns.at(i)->setIcon(QIcon(pixNormal));
|
||||
btns.at(i)->setIconSize(QSize(iconWidth, iconHeight));
|
||||
btns.at(i)->installEventFilter(this);
|
||||
|
||||
this->btns.append(btns.at(i));
|
||||
this->pixNormal.append(pixNormal);
|
||||
this->pixDark.append(pixDark);
|
||||
}
|
||||
}
|
||||
|
||||
void IconHelper::setStyle(QFrame *frame, QList<QToolButton *> btns, QList<int> pixChar,
|
||||
quint32 iconSize, quint32 iconWidth, quint32 iconHeight,
|
||||
const QString &normalBgColor, const QString &darkBgColor,
|
||||
const QString &normalTextColor, const QString &darkTextColor)
|
||||
{
|
||||
int btnCount = btns.count();
|
||||
int charCount = pixChar.count();
|
||||
if (btnCount <= 0 || charCount <= 0 || btnCount != charCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList qss;
|
||||
qss.append(QString("QFrame>QToolButton{border-style:none;border-width:0px;}"));
|
||||
qss.append(QString("QFrame>QToolButton{background-color:%1;color:%2;}")
|
||||
.arg(normalBgColor).arg(normalTextColor));
|
||||
qss.append(QString("QFrame>QToolButton:hover,QFrame>QToolButton:pressed,QFrame>QToolButton:checked{background-color:%1;color:%2;}")
|
||||
.arg(darkBgColor).arg(darkTextColor));
|
||||
|
||||
frame->setStyleSheet(qss.join(""));
|
||||
|
||||
for (int i = 0; i < btnCount; i++) {
|
||||
//存储对应按钮对象,方便鼠标移上去的时候切换图片
|
||||
QPixmap pixNormal = getPixmap(normalTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight);
|
||||
QPixmap pixDark = getPixmap(darkTextColor, QChar(pixChar.at(i)), iconSize, iconWidth, iconHeight);
|
||||
|
||||
btns.at(i)->setIcon(QIcon(pixNormal));
|
||||
btns.at(i)->setIconSize(QSize(iconWidth, iconHeight));
|
||||
btns.at(i)->installEventFilter(this);
|
||||
|
||||
this->btns.append(btns.at(i));
|
||||
this->pixNormal.append(pixNormal);
|
||||
this->pixDark.append(pixDark);
|
||||
}
|
||||
}
|
||||
|
||||
bool IconHelper::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (watched->inherits("QToolButton")) {
|
||||
QToolButton *btn = (QToolButton *)watched;
|
||||
int index = btns.indexOf(btn);
|
||||
if (index >= 0) {
|
||||
if (event->type() == QEvent::Enter) {
|
||||
btn->setIcon(QIcon(pixDark.at(index)));
|
||||
} else if (event->type() == QEvent::Leave) {
|
||||
if (btn->isChecked()) {
|
||||
btn->setIcon(QIcon(pixDark.at(index)));
|
||||
} else {
|
||||
btn->setIcon(QIcon(pixNormal.at(index)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
64
navbutton/iconhelper.h
Normal file
64
navbutton/iconhelper.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef ICONHELPER_H
|
||||
#define ICONHELPER_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
|
||||
#include <QtWidgets>
|
||||
#endif
|
||||
|
||||
//图形字体处理类
|
||||
class IconHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static IconHelper *Instance();
|
||||
explicit IconHelper(QObject *parent = 0);
|
||||
|
||||
void setIcon(QLabel *lab, const QChar &str, quint32 size = 12);
|
||||
void setIcon(QAbstractButton *btn, const QChar &str, quint32 size = 12);
|
||||
QPixmap getPixmap(const QColor &color, const QChar &str, quint32 size = 12,
|
||||
quint32 pixWidth = 15, quint32 pixHeight = 15,
|
||||
int flags = Qt::AlignCenter);
|
||||
|
||||
//根据按钮获取该按钮对应的图标
|
||||
QPixmap getPixmap(QToolButton *btn, bool normal);
|
||||
|
||||
//指定导航面板样式,不带图标
|
||||
static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3,
|
||||
const QString &borderColor = "#029FEA",
|
||||
const QString &normalBgColor = "#292F38",
|
||||
const QString &darkBgColor = "#1D2025",
|
||||
const QString &normalTextColor = "#54626F",
|
||||
const QString &darkTextColor = "#FDFDFD");
|
||||
|
||||
//指定导航面板样式,带图标和效果切换
|
||||
void setStyle(QWidget *widget, QList<QToolButton *> btns, QList<int> pixChar,
|
||||
quint32 iconSize = 12, quint32 iconWidth = 15, quint32 iconHeight = 15,
|
||||
const QString &type = "left", int borderWidth = 3,
|
||||
const QString &borderColor = "#029FEA",
|
||||
const QString &normalBgColor = "#292F38",
|
||||
const QString &darkBgColor = "#1D2025",
|
||||
const QString &normalTextColor = "#54626F",
|
||||
const QString &darkTextColor = "#FDFDFD");
|
||||
|
||||
//指定导航按钮样式,带图标和效果切换
|
||||
void setStyle(QFrame *frame, QList<QToolButton *> btns, QList<int> pixChar,
|
||||
quint32 iconSize = 12, quint32 iconWidth = 15, quint32 iconHeight = 15,
|
||||
const QString &normalBgColor = "#2FC5A2",
|
||||
const QString &darkBgColor = "#3EA7E9",
|
||||
const QString &normalTextColor = "#EEEEEE",
|
||||
const QString &darkTextColor = "#FFFFFF");
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<IconHelper> self;
|
||||
QFont iconFont; //图形字体
|
||||
QList<QToolButton *> btns; //按钮队列
|
||||
QList<QPixmap> pixNormal; //正常图片队列
|
||||
QList<QPixmap> pixDark; //加深图片队列
|
||||
};
|
||||
#endif // ICONHELPER_H
|
||||
BIN
navbutton/image/fontawesome-webfont.ttf
Normal file
BIN
navbutton/image/fontawesome-webfont.ttf
Normal file
Binary file not shown.
31
navbutton/main.cpp
Normal file
31
navbutton/main.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "frmnavbutton.h"
|
||||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
a.setFont(QFont("Microsoft Yahei", 9));
|
||||
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#if _MSC_VER
|
||||
QTextCodec *codec = QTextCodec::codecForName("gbk");
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
#endif
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
QTextCodec::setCodecForCStrings(codec);
|
||||
QTextCodec::setCodecForTr(codec);
|
||||
#else
|
||||
QTextCodec *codec = QTextCodec::codecForName("utf-8");
|
||||
QTextCodec::setCodecForLocale(codec);
|
||||
#endif
|
||||
|
||||
frmNavButton w;
|
||||
w.setWindowTitle("导航按钮控件");
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
5
navbutton/main.qrc
Normal file
5
navbutton/main.qrc
Normal file
@@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>image/fontawesome-webfont.ttf</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
629
navbutton/navbutton.cpp
Normal file
629
navbutton/navbutton.cpp
Normal file
@@ -0,0 +1,629 @@
|
||||
#pragma execution_character_set("utf-8")
|
||||
|
||||
#include "navbutton.h"
|
||||
#include "qpainter.h"
|
||||
#include "qdebug.h"
|
||||
|
||||
NavButton::NavButton(QWidget *parent) : QPushButton(parent)
|
||||
{
|
||||
paddingLeft = 20;
|
||||
paddingRight = 5;
|
||||
paddingTop = 5;
|
||||
paddingBottom = 5;
|
||||
textAlign = TextAlign_Left;
|
||||
|
||||
showTriangle = false;
|
||||
triangleLen = 5;
|
||||
trianglePosition = TrianglePosition_Right;
|
||||
triangleColor = QColor(255, 255, 255);
|
||||
|
||||
showIcon = false;
|
||||
iconSpace = 10;
|
||||
iconSize = QSize(16, 16);
|
||||
iconNormal = QPixmap();
|
||||
iconHover = QPixmap();
|
||||
iconCheck = QPixmap();
|
||||
|
||||
showLine = true;
|
||||
lineSpace = 0;
|
||||
lineWidth = 5;
|
||||
linePosition = LinePosition_Left;
|
||||
lineColor = QColor(0, 187, 158);
|
||||
|
||||
normalBgColor = QColor(230, 230, 230);
|
||||
hoverBgColor = QColor(130, 130, 130);
|
||||
checkBgColor = QColor(80, 80, 80);
|
||||
normalTextColor = QColor(100, 100, 100);
|
||||
hoverTextColor = QColor(255, 255, 255);
|
||||
checkTextColor = QColor(255, 255, 255);
|
||||
|
||||
normalBgBrush = Qt::NoBrush;
|
||||
hoverBgBrush = Qt::NoBrush;
|
||||
checkBgBrush = Qt::NoBrush;
|
||||
|
||||
hover = false;
|
||||
setCheckable(true);
|
||||
}
|
||||
|
||||
void NavButton::enterEvent(QEvent *)
|
||||
{
|
||||
hover = true;
|
||||
this->update();
|
||||
}
|
||||
|
||||
void NavButton::leaveEvent(QEvent *)
|
||||
{
|
||||
hover = false;
|
||||
this->update();
|
||||
}
|
||||
|
||||
void NavButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
//绘制准备工作,启用反锯齿
|
||||
QPainter painter(this);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
|
||||
|
||||
//绘制背景
|
||||
drawBg(&painter);
|
||||
//绘制文字
|
||||
drawText(&painter);
|
||||
//绘制图标
|
||||
drawIcon(&painter);
|
||||
//绘制边框线条
|
||||
drawLine(&painter);
|
||||
//绘制倒三角
|
||||
drawTriangle(&painter);
|
||||
}
|
||||
|
||||
void NavButton::drawBg(QPainter *painter)
|
||||
{
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
|
||||
int width = this->width();
|
||||
int height = this->height();
|
||||
|
||||
QRect bgRect;
|
||||
if (linePosition == LinePosition_Left) {
|
||||
bgRect = QRect(lineSpace, 0, width - lineSpace, height);
|
||||
} else if (linePosition == LinePosition_Right) {
|
||||
bgRect = QRect(0, 0, width - lineSpace, height);
|
||||
} else if (linePosition == LinePosition_Top) {
|
||||
bgRect = QRect(0, lineSpace, width, height - lineSpace);
|
||||
} else if (linePosition == LinePosition_Bottom) {
|
||||
bgRect = QRect(0, 0, width, height - lineSpace);
|
||||
}
|
||||
|
||||
//如果画刷存在则取画刷
|
||||
QBrush bgBrush;
|
||||
if (isChecked()) {
|
||||
bgBrush = checkBgBrush;
|
||||
} else if (hover) {
|
||||
bgBrush = hoverBgBrush;
|
||||
} else {
|
||||
bgBrush = normalBgBrush;
|
||||
}
|
||||
|
||||
if (bgBrush != Qt::NoBrush) {
|
||||
painter->setBrush(bgBrush);
|
||||
} else {
|
||||
//根据当前状态选择对应颜色
|
||||
QColor bgColor;
|
||||
if (isChecked()) {
|
||||
bgColor = checkBgColor;
|
||||
} else if (hover) {
|
||||
bgColor = hoverBgColor;
|
||||
} else {
|
||||
bgColor = normalBgColor;
|
||||
}
|
||||
|
||||
painter->setBrush(bgColor);
|
||||
}
|
||||
|
||||
painter->drawRect(bgRect);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void NavButton::drawText(QPainter *painter)
|
||||
{
|
||||
painter->save();
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
|
||||
//根据当前状态选择对应颜色
|
||||
QColor textColor;
|
||||
if (isChecked()) {
|
||||
textColor = checkTextColor;
|
||||
} else if (hover) {
|
||||
textColor = hoverTextColor;
|
||||
} else {
|
||||
textColor = normalTextColor;
|
||||
}
|
||||
|
||||
QRect textRect = QRect(paddingLeft, paddingTop, width() - paddingLeft - paddingRight, height() - paddingTop - paddingBottom);
|
||||
painter->setPen(textColor);
|
||||
painter->drawText(textRect, textAlign | Qt::AlignVCenter, text());
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void NavButton::drawIcon(QPainter *painter)
|
||||
{
|
||||
if (!showIcon) {
|
||||
return;
|
||||
}
|
||||
|
||||
painter->save();
|
||||
|
||||
QPixmap pix;
|
||||
if (isChecked()) {
|
||||
pix = iconCheck;
|
||||
} else if (hover) {
|
||||
pix = iconHover;
|
||||
} else {
|
||||
pix = iconNormal;
|
||||
}
|
||||
|
||||
if (!pix.isNull()) {
|
||||
//等比例平滑缩放图标
|
||||
pix = pix.scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
painter->drawPixmap(iconSpace, (height() - iconSize.height()) / 2, pix);
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void NavButton::drawLine(QPainter *painter)
|
||||
{
|
||||
if (!showLine) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isChecked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
painter->save();
|
||||
|
||||
QPen pen;
|
||||
pen.setWidth(lineWidth);
|
||||
pen.setColor(lineColor);
|
||||
painter->setPen(pen);
|
||||
|
||||
//根据线条位置设置线条坐标
|
||||
QPoint pointStart, pointEnd;
|
||||
if (linePosition == LinePosition_Left) {
|
||||
pointStart = QPoint(0, 0);
|
||||
pointEnd = QPoint(0, height());
|
||||
} else if (linePosition == LinePosition_Right) {
|
||||
pointStart = QPoint(width(), 0);
|
||||
pointEnd = QPoint(width(), height());
|
||||
} else if (linePosition == LinePosition_Top) {
|
||||
pointStart = QPoint(0, 0);
|
||||
pointEnd = QPoint(width(), 0);
|
||||
} else if (linePosition == LinePosition_Bottom) {
|
||||
pointStart = QPoint(0, height());
|
||||
pointEnd = QPoint(width(), height());
|
||||
}
|
||||
|
||||
painter->drawLine(pointStart, pointEnd);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void NavButton::drawTriangle(QPainter *painter)
|
||||
{
|
||||
if (!showTriangle) {
|
||||
return;
|
||||
}
|
||||
|
||||
//选中或者悬停显示
|
||||
if (!hover && !isChecked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(triangleColor);
|
||||
|
||||
//绘制在右侧中间,根据设定的倒三角的边长设定三个点位置
|
||||
int width = this->width();
|
||||
int height = this->height();
|
||||
int midWidth = width / 2;
|
||||
int midHeight = height / 2;
|
||||
|
||||
QPolygon pts;
|
||||
if (trianglePosition == TrianglePosition_Left) {
|
||||
pts.setPoints(3, triangleLen, midHeight, 0, midHeight - triangleLen, 0, midHeight + triangleLen);
|
||||
} else if (trianglePosition == TrianglePosition_Right) {
|
||||
pts.setPoints(3, width - triangleLen, midHeight, width, midHeight - triangleLen, width, midHeight + triangleLen);
|
||||
} else if (trianglePosition == TrianglePosition_Top) {
|
||||
pts.setPoints(3, midWidth, triangleLen, midWidth - triangleLen, 0, midWidth + triangleLen, 0);
|
||||
} else if (trianglePosition == TrianglePosition_Bottom) {
|
||||
pts.setPoints(3, midWidth, height - triangleLen, midWidth - triangleLen, height, midWidth + triangleLen, height);
|
||||
}
|
||||
|
||||
painter->drawPolygon(pts);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
int NavButton::getPaddingLeft() const
|
||||
{
|
||||
return this->paddingLeft;
|
||||
}
|
||||
|
||||
int NavButton::getPaddingRight() const
|
||||
{
|
||||
return this->paddingRight;
|
||||
}
|
||||
|
||||
int NavButton::getPaddingTop() const
|
||||
{
|
||||
return this->paddingTop;
|
||||
}
|
||||
|
||||
int NavButton::getPaddingBottom() const
|
||||
{
|
||||
return this->paddingBottom;
|
||||
}
|
||||
|
||||
NavButton::TextAlign NavButton::getTextAlign() const
|
||||
{
|
||||
return this->textAlign;
|
||||
}
|
||||
|
||||
bool NavButton::getShowTriangle() const
|
||||
{
|
||||
return this->showTriangle;
|
||||
}
|
||||
|
||||
int NavButton::getTriangleLen() const
|
||||
{
|
||||
return this->triangleLen;
|
||||
}
|
||||
|
||||
NavButton::TrianglePosition NavButton::getTrianglePosition() const
|
||||
{
|
||||
return this->trianglePosition;
|
||||
}
|
||||
|
||||
QColor NavButton::getTriangleColor() const
|
||||
{
|
||||
return this->triangleColor;
|
||||
}
|
||||
|
||||
bool NavButton::getShowIcon() const
|
||||
{
|
||||
return this->showIcon;
|
||||
}
|
||||
|
||||
int NavButton::getIconSpace() const
|
||||
{
|
||||
return this->iconSpace;
|
||||
}
|
||||
|
||||
QSize NavButton::getIconSize() const
|
||||
{
|
||||
return this->iconSize;
|
||||
}
|
||||
|
||||
QPixmap NavButton::getIconNormal() const
|
||||
{
|
||||
return this->iconNormal;
|
||||
}
|
||||
|
||||
QPixmap NavButton::getIconHover() const
|
||||
{
|
||||
return this->iconHover;
|
||||
}
|
||||
|
||||
QPixmap NavButton::getIconCheck() const
|
||||
{
|
||||
return this->iconCheck;
|
||||
}
|
||||
|
||||
bool NavButton::getShowLine() const
|
||||
{
|
||||
return this->showLine;
|
||||
}
|
||||
|
||||
int NavButton::getLineSpace() const
|
||||
{
|
||||
return this->lineSpace;
|
||||
}
|
||||
|
||||
int NavButton::getLineWidth() const
|
||||
{
|
||||
return this->lineWidth;
|
||||
}
|
||||
|
||||
NavButton::LinePosition NavButton::getLinePosition() const
|
||||
{
|
||||
return this->linePosition;
|
||||
}
|
||||
|
||||
QColor NavButton::getLineColor() const
|
||||
{
|
||||
return this->lineColor;
|
||||
}
|
||||
|
||||
QColor NavButton::getNormalBgColor() const
|
||||
{
|
||||
return this->normalBgColor;
|
||||
}
|
||||
|
||||
QColor NavButton::getHoverBgColor() const
|
||||
{
|
||||
return this->hoverBgColor;
|
||||
}
|
||||
|
||||
QColor NavButton::getCheckBgColor() const
|
||||
{
|
||||
return this->checkBgColor;
|
||||
}
|
||||
|
||||
QColor NavButton::getNormalTextColor() const
|
||||
{
|
||||
return this->normalTextColor;
|
||||
}
|
||||
|
||||
QColor NavButton::getHoverTextColor() const
|
||||
{
|
||||
return this->hoverTextColor;
|
||||
}
|
||||
|
||||
QColor NavButton::getCheckTextColor() const
|
||||
{
|
||||
return this->checkTextColor;
|
||||
}
|
||||
|
||||
QSize NavButton::sizeHint() const
|
||||
{
|
||||
return QSize(100, 30);
|
||||
}
|
||||
|
||||
QSize NavButton::minimumSizeHint() const
|
||||
{
|
||||
return QSize(20, 10);
|
||||
}
|
||||
|
||||
void NavButton::setPaddingLeft(int paddingLeft)
|
||||
{
|
||||
if (this->paddingLeft != paddingLeft) {
|
||||
this->paddingLeft = paddingLeft;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setPaddingRight(int paddingRight)
|
||||
{
|
||||
if (this->paddingRight != paddingRight) {
|
||||
this->paddingRight = paddingRight;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setPaddingTop(int paddingTop)
|
||||
{
|
||||
if (this->paddingTop != paddingTop) {
|
||||
this->paddingTop = paddingTop;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setPaddingBottom(int paddingBottom)
|
||||
{
|
||||
if (this->paddingBottom != paddingBottom) {
|
||||
this->paddingBottom = paddingBottom;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setPadding(int padding)
|
||||
{
|
||||
setPadding(padding, padding, padding, padding);
|
||||
}
|
||||
|
||||
void NavButton::setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom)
|
||||
{
|
||||
this->paddingLeft = paddingLeft;
|
||||
this->paddingRight = paddingRight;
|
||||
this->paddingTop = paddingTop;
|
||||
this->paddingBottom = paddingBottom;
|
||||
this->update();
|
||||
}
|
||||
|
||||
void NavButton::setTextAlign(const NavButton::TextAlign &textAlign)
|
||||
{
|
||||
if (this->textAlign != textAlign) {
|
||||
this->textAlign = textAlign;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setShowTriangle(bool showTriangle)
|
||||
{
|
||||
if (this->showTriangle != showTriangle) {
|
||||
this->showTriangle = showTriangle;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setTriangleLen(int triangleLen)
|
||||
{
|
||||
if (this->triangleLen != triangleLen) {
|
||||
this->triangleLen = triangleLen;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setTrianglePosition(const NavButton::TrianglePosition &trianglePosition)
|
||||
{
|
||||
if (this->trianglePosition != trianglePosition) {
|
||||
this->trianglePosition = trianglePosition;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setTriangleColor(const QColor &triangleColor)
|
||||
{
|
||||
if (this->triangleColor != triangleColor) {
|
||||
this->triangleColor = triangleColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setShowIcon(bool showIcon)
|
||||
{
|
||||
if (this->showIcon != showIcon) {
|
||||
this->showIcon = showIcon;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setIconSpace(int iconSpace)
|
||||
{
|
||||
if (this->iconSpace != iconSpace) {
|
||||
this->iconSpace = iconSpace;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setIconSize(const QSize &iconSize)
|
||||
{
|
||||
if (this->iconSize != iconSize) {
|
||||
this->iconSize = iconSize;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setIconNormal(const QPixmap &iconNormal)
|
||||
{
|
||||
this->iconNormal = iconNormal;
|
||||
this->update();
|
||||
}
|
||||
|
||||
void NavButton::setIconHover(const QPixmap &iconHover)
|
||||
{
|
||||
this->iconHover = iconHover;
|
||||
this->update();
|
||||
}
|
||||
|
||||
void NavButton::setIconCheck(const QPixmap &iconCheck)
|
||||
{
|
||||
this->iconCheck = iconCheck;
|
||||
this->update();
|
||||
}
|
||||
|
||||
void NavButton::setShowLine(bool showLine)
|
||||
{
|
||||
if (this->showLine != showLine) {
|
||||
this->showLine = showLine;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setLineSpace(int lineSpace)
|
||||
{
|
||||
if (this->lineSpace != lineSpace) {
|
||||
this->lineSpace = lineSpace;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setLineWidth(int lineWidth)
|
||||
{
|
||||
if (this->lineWidth != lineWidth) {
|
||||
this->lineWidth = lineWidth;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setLinePosition(const NavButton::LinePosition &linePosition)
|
||||
{
|
||||
if (this->linePosition != linePosition) {
|
||||
this->linePosition = linePosition;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setLineColor(const QColor &lineColor)
|
||||
{
|
||||
if (this->lineColor != lineColor) {
|
||||
this->lineColor = lineColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setNormalBgColor(const QColor &normalBgColor)
|
||||
{
|
||||
if (this->normalBgColor != normalBgColor) {
|
||||
this->normalBgColor = normalBgColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setHoverBgColor(const QColor &hoverBgColor)
|
||||
{
|
||||
if (this->hoverBgColor != hoverBgColor) {
|
||||
this->hoverBgColor = hoverBgColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setCheckBgColor(const QColor &checkBgColor)
|
||||
{
|
||||
if (this->checkBgColor != checkBgColor) {
|
||||
this->checkBgColor = checkBgColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setNormalTextColor(const QColor &normalTextColor)
|
||||
{
|
||||
if (this->normalTextColor != normalTextColor) {
|
||||
this->normalTextColor = normalTextColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setHoverTextColor(const QColor &hoverTextColor)
|
||||
{
|
||||
if (this->hoverTextColor != hoverTextColor) {
|
||||
this->hoverTextColor = hoverTextColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setCheckTextColor(const QColor &checkTextColor)
|
||||
{
|
||||
if (this->checkTextColor != checkTextColor) {
|
||||
this->checkTextColor = checkTextColor;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setNormalBgBrush(const QBrush &normalBgBrush)
|
||||
{
|
||||
if (this->normalBgBrush != normalBgBrush) {
|
||||
this->normalBgBrush = normalBgBrush;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setHoverBgBrush(const QBrush &hoverBgBrush)
|
||||
{
|
||||
if (this->hoverBgBrush != hoverBgBrush) {
|
||||
this->hoverBgBrush = hoverBgBrush;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
|
||||
void NavButton::setCheckBgBrush(const QBrush &checkBgBrush)
|
||||
{
|
||||
if (this->checkBgBrush != checkBgBrush) {
|
||||
this->checkBgBrush = checkBgBrush;
|
||||
this->update();
|
||||
}
|
||||
}
|
||||
251
navbutton/navbutton.h
Normal file
251
navbutton/navbutton.h
Normal file
@@ -0,0 +1,251 @@
|
||||
#ifndef NAVBUTTON_H
|
||||
#define NAVBUTTON_H
|
||||
|
||||
/**
|
||||
* 导航按钮控件 作者:feiyangqingyun(QQ:517216493) 2017-12-19
|
||||
* 1:可设置文字的左侧+右侧+顶部+底部间隔
|
||||
* 2:可设置文字对齐方式
|
||||
* 3:可设置显示倒三角/倒三角边长/倒三角位置/倒三角颜色
|
||||
* 4:可设置显示图标/图标间隔/图标尺寸/正常状态图标/悬停状态图标/选中状态图标
|
||||
* 5:可设置显示边框线条/线条宽度/线条间隔/线条位置/线条颜色
|
||||
* 6:可设置正常背景颜色/悬停背景颜色/选中背景颜色
|
||||
* 7:可设置正常文字颜色/悬停文字颜色/选中文字颜色
|
||||
* 8:可设置背景颜色为画刷颜色
|
||||
*/
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
#ifdef quc
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT NavButton : public QPushButton
|
||||
#else
|
||||
class NavButton : public QPushButton
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(TextAlign)
|
||||
Q_ENUMS(TrianglePosition)
|
||||
Q_ENUMS(LinePosition)
|
||||
Q_ENUMS(IconPosition)
|
||||
|
||||
Q_PROPERTY(int paddingLeft READ getPaddingLeft WRITE setPaddingLeft)
|
||||
Q_PROPERTY(int paddingRight READ getPaddingRight WRITE setPaddingRight)
|
||||
Q_PROPERTY(int paddingTop READ getPaddingTop WRITE setPaddingTop)
|
||||
Q_PROPERTY(int paddingBottom READ getPaddingBottom WRITE setPaddingBottom)
|
||||
Q_PROPERTY(TextAlign textAlign READ getTextAlign WRITE setTextAlign)
|
||||
|
||||
Q_PROPERTY(bool showTriangle READ getShowTriangle WRITE setShowTriangle)
|
||||
Q_PROPERTY(int triangleLen READ getTriangleLen WRITE setTriangleLen)
|
||||
Q_PROPERTY(TrianglePosition trianglePosition READ getTrianglePosition WRITE setTrianglePosition)
|
||||
Q_PROPERTY(QColor triangleColor READ getTriangleColor WRITE setTriangleColor)
|
||||
|
||||
Q_PROPERTY(bool showIcon READ getShowIcon WRITE setShowIcon)
|
||||
Q_PROPERTY(int iconSpace READ getIconSpace WRITE setIconSpace)
|
||||
Q_PROPERTY(QSize iconSize READ getIconSize WRITE setIconSize)
|
||||
Q_PROPERTY(QPixmap iconNormal READ getIconNormal WRITE setIconNormal)
|
||||
Q_PROPERTY(QPixmap iconHover READ getIconHover WRITE setIconHover)
|
||||
Q_PROPERTY(QPixmap iconCheck READ getIconCheck WRITE setIconCheck)
|
||||
|
||||
Q_PROPERTY(bool showLine READ getShowLine WRITE setShowLine)
|
||||
Q_PROPERTY(int lineSpace READ getLineSpace WRITE setLineSpace)
|
||||
Q_PROPERTY(int lineWidth READ getLineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY(LinePosition linePosition READ getLinePosition WRITE setLinePosition)
|
||||
Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor)
|
||||
|
||||
Q_PROPERTY(QColor normalBgColor READ getNormalBgColor WRITE setNormalBgColor)
|
||||
Q_PROPERTY(QColor hoverBgColor READ getHoverBgColor WRITE setHoverBgColor)
|
||||
Q_PROPERTY(QColor checkBgColor READ getCheckBgColor WRITE setCheckBgColor)
|
||||
Q_PROPERTY(QColor normalTextColor READ getNormalTextColor WRITE setNormalTextColor)
|
||||
Q_PROPERTY(QColor hoverTextColor READ getHoverTextColor WRITE setHoverTextColor)
|
||||
Q_PROPERTY(QColor checkTextColor READ getCheckTextColor WRITE setCheckTextColor)
|
||||
|
||||
public:
|
||||
enum TextAlign {
|
||||
TextAlign_Left = 0x0001, //左侧对齐
|
||||
TextAlign_Right = 0x0002, //右侧对齐
|
||||
TextAlign_Top = 0x0020, //顶部对齐
|
||||
TextAlign_Bottom = 0x0040, //底部对齐
|
||||
TextAlign_Center = 0x0004 //居中对齐
|
||||
};
|
||||
|
||||
enum TrianglePosition {
|
||||
TrianglePosition_Left = 0, //左侧
|
||||
TrianglePosition_Right = 1, //右侧
|
||||
TrianglePosition_Top = 2, //顶部
|
||||
TrianglePosition_Bottom = 3 //底部
|
||||
};
|
||||
|
||||
enum IconPosition {
|
||||
IconPosition_Left = 0, //左侧
|
||||
IconPosition_Right = 1, //右侧
|
||||
IconPosition_Top = 2, //顶部
|
||||
IconPosition_Bottom = 3 //底部
|
||||
};
|
||||
|
||||
enum LinePosition {
|
||||
LinePosition_Left = 0, //左侧
|
||||
LinePosition_Right = 1, //右侧
|
||||
LinePosition_Top = 2, //顶部
|
||||
LinePosition_Bottom = 3 //底部
|
||||
};
|
||||
|
||||
explicit NavButton(QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
void enterEvent(QEvent *);
|
||||
void leaveEvent(QEvent *);
|
||||
void paintEvent(QPaintEvent *);
|
||||
void drawBg(QPainter *painter);
|
||||
void drawText(QPainter *painter);
|
||||
void drawIcon(QPainter *painter);
|
||||
void drawLine(QPainter *painter);
|
||||
void drawTriangle(QPainter *painter);
|
||||
|
||||
private:
|
||||
int paddingLeft; //文字左侧间隔
|
||||
int paddingRight; //文字右侧间隔
|
||||
int paddingTop; //文字顶部间隔
|
||||
int paddingBottom; //文字底部间隔
|
||||
TextAlign textAlign; //文字对齐
|
||||
|
||||
bool showTriangle; //显示倒三角
|
||||
int triangleLen; //倒三角边长
|
||||
TrianglePosition trianglePosition; //倒三角位置
|
||||
QColor triangleColor; //倒三角颜色
|
||||
|
||||
bool showIcon; //显示图标
|
||||
int iconSpace; //图标间隔
|
||||
QSize iconSize; //图标尺寸
|
||||
QPixmap iconNormal; //正常图标
|
||||
QPixmap iconHover; //悬停图标
|
||||
QPixmap iconCheck; //选中图标
|
||||
|
||||
bool showLine; //显示线条
|
||||
int lineSpace; //线条间隔
|
||||
int lineWidth; //线条宽度
|
||||
LinePosition linePosition; //线条位置
|
||||
QColor lineColor; //线条颜色
|
||||
|
||||
QColor normalBgColor; //正常背景颜色
|
||||
QColor hoverBgColor; //悬停背景颜色
|
||||
QColor checkBgColor; //选中背景颜色
|
||||
QColor normalTextColor; //正常文字颜色
|
||||
QColor hoverTextColor; //悬停文字颜色
|
||||
QColor checkTextColor; //选中文字颜色
|
||||
|
||||
QBrush normalBgBrush; //正常背景画刷
|
||||
QBrush hoverBgBrush; //悬停背景画刷
|
||||
QBrush checkBgBrush; //选中背景画刷
|
||||
|
||||
bool hover; //悬停标志位
|
||||
|
||||
public:
|
||||
int getPaddingLeft() const;
|
||||
int getPaddingRight() const;
|
||||
int getPaddingTop() const;
|
||||
int getPaddingBottom() const;
|
||||
TextAlign getTextAlign() const;
|
||||
|
||||
bool getShowTriangle() const;
|
||||
int getTriangleLen() const;
|
||||
TrianglePosition getTrianglePosition()const;
|
||||
QColor getTriangleColor() const;
|
||||
|
||||
bool getShowIcon() const;
|
||||
int getIconSpace() const;
|
||||
QSize getIconSize() const;
|
||||
QPixmap getIconNormal() const;
|
||||
QPixmap getIconHover() const;
|
||||
QPixmap getIconCheck() const;
|
||||
|
||||
bool getShowLine() const;
|
||||
int getLineSpace() const;
|
||||
int getLineWidth() const;
|
||||
LinePosition getLinePosition() const;
|
||||
QColor getLineColor() const;
|
||||
|
||||
QColor getNormalBgColor() const;
|
||||
QColor getHoverBgColor() const;
|
||||
QColor getCheckBgColor() const;
|
||||
QColor getNormalTextColor() const;
|
||||
QColor getHoverTextColor() const;
|
||||
QColor getCheckTextColor() const;
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置文字间隔
|
||||
void setPaddingLeft(int paddingLeft);
|
||||
void setPaddingRight(int paddingRight);
|
||||
void setPaddingTop(int paddingTop);
|
||||
void setPaddingBottom(int paddingBottom);
|
||||
void setPadding(int padding);
|
||||
void setPadding(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom);
|
||||
|
||||
//设置文字对齐
|
||||
void setTextAlign(const TextAlign &textAlign);
|
||||
|
||||
//设置显示倒三角
|
||||
void setShowTriangle(bool showTriangle);
|
||||
//设置倒三角边长
|
||||
void setTriangleLen(int triangleLen);
|
||||
//设置倒三角位置
|
||||
void setTrianglePosition(const TrianglePosition &trianglePosition);
|
||||
//设置倒三角颜色
|
||||
void setTriangleColor(const QColor &triangleColor);
|
||||
|
||||
//设置显示图标
|
||||
void setShowIcon(bool showIcon);
|
||||
//设置图标间隔
|
||||
void setIconSpace(int iconSpace);
|
||||
//设置图标尺寸
|
||||
void setIconSize(const QSize &iconSize);
|
||||
//设置正常图标
|
||||
void setIconNormal(const QPixmap &iconNormal);
|
||||
//设置悬停图标
|
||||
void setIconHover(const QPixmap &iconHover);
|
||||
//设置按下图标
|
||||
void setIconCheck(const QPixmap &iconCheck);
|
||||
|
||||
//设置显示线条
|
||||
void setShowLine(bool showLine);
|
||||
//设置线条间隔
|
||||
void setLineSpace(int lineSpace);
|
||||
//设置线条宽度
|
||||
void setLineWidth(int lineWidth);
|
||||
//设置线条位置
|
||||
void setLinePosition(const LinePosition &linePosition);
|
||||
//设置线条颜色
|
||||
void setLineColor(const QColor &lineColor);
|
||||
|
||||
//设置正常背景颜色
|
||||
void setNormalBgColor(const QColor &normalBgColor);
|
||||
//设置悬停背景颜色
|
||||
void setHoverBgColor(const QColor &hoverBgColor);
|
||||
//设置选中背景颜色
|
||||
void setCheckBgColor(const QColor &checkBgColor);
|
||||
|
||||
//设置正常文字颜色
|
||||
void setNormalTextColor(const QColor &normalTextColor);
|
||||
//设置悬停文字颜色
|
||||
void setHoverTextColor(const QColor &hoverTextColor);
|
||||
//设置选中文字颜色
|
||||
void setCheckTextColor(const QColor &checkTextColor);
|
||||
|
||||
//设置正常背景画刷
|
||||
void setNormalBgBrush(const QBrush &normalBgBrush);
|
||||
//设置悬停背景画刷
|
||||
void setHoverBgBrush(const QBrush &hoverBgBrush);
|
||||
//设置选中背景画刷
|
||||
void setCheckBgBrush(const QBrush &checkBgBrush);
|
||||
|
||||
};
|
||||
|
||||
#endif // NAVBUTTON_H
|
||||
27
navbutton/navbutton.pro
Normal file
27
navbutton/navbutton.pro
Normal file
@@ -0,0 +1,27 @@
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2017-02-08T15:12:35
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
TARGET = navbutton
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$PWD/../bin
|
||||
CONFIG += warn_off
|
||||
|
||||
SOURCES += main.cpp
|
||||
SOURCES += iconhelper.cpp
|
||||
SOURCES += frmnavbutton.cpp
|
||||
SOURCES += navbutton.cpp
|
||||
|
||||
HEADERS += frmnavbutton.h
|
||||
HEADERS += iconhelper.h
|
||||
HEADERS += navbutton.h
|
||||
|
||||
FORMS += frmnavbutton.ui
|
||||
|
||||
RESOURCES += main.qrc
|
||||
9
nettool/api/api.pri
Normal file
9
nettool/api/api.pri
Normal file
@@ -0,0 +1,9 @@
|
||||
HEADERS += \
|
||||
$$PWD/app.h \
|
||||
$$PWD/quiwidget.h \
|
||||
$$PWD/tcpserver.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/app.cpp \
|
||||
$$PWD/quiwidget.cpp \
|
||||
$$PWD/tcpserver.cpp
|
||||
226
nettool/api/app.cpp
Normal file
226
nettool/api/app.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
#include "app.h"
|
||||
#include "quiwidget.h"
|
||||
|
||||
QString App::ConfigFile = "config.ini";
|
||||
QString App::SendFileName = "send.txt";
|
||||
QString App::DeviceFileName = "device.txt";
|
||||
|
||||
int App::CurrentIndex = 0;
|
||||
|
||||
bool App::HexSendTcpClient = false;
|
||||
bool App::HexReceiveTcpClient = false;
|
||||
bool App::AsciiTcpClient = false;
|
||||
bool App::DebugTcpClient = false;
|
||||
bool App::AutoSendTcpClient = false;
|
||||
int App::IntervalTcpClient = 1000;
|
||||
QString App::TcpServerIP = "127.0.0.1";
|
||||
int App::TcpServerPort = 6000;
|
||||
|
||||
bool App::HexSendTcpServer = false;
|
||||
bool App::HexReceiveTcpServer = false;
|
||||
bool App::AsciiTcpServer = false;
|
||||
bool App::DebugTcpServer = false;
|
||||
bool App::AutoSendTcpServer = false;
|
||||
bool App::SelectAllTcpServer = false;
|
||||
int App::IntervalTcpServer = 1000;
|
||||
int App::TcpListenPort = 6000;
|
||||
|
||||
bool App::HexSendUdpServer = false;
|
||||
bool App::HexReceiveUdpServer = false;
|
||||
bool App::AsciiUdpServer = false;
|
||||
bool App::DebugUdpServer = false;
|
||||
bool App::AutoSendUdpServer = false;
|
||||
int App::IntervalUdpServer = 1000;
|
||||
int App::UdpListenPort = 6000;
|
||||
QString App::UdpServerIP = "127.0.0.1";
|
||||
int App::UdpServerPort = 6000;
|
||||
|
||||
void App::readConfig()
|
||||
{
|
||||
if (!checkConfig()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QSettings set(App::ConfigFile, QSettings::IniFormat);
|
||||
|
||||
set.beginGroup("AppConfig");
|
||||
App::CurrentIndex = set.value("CurrentIndex").toInt();
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("TcpClientConfig");
|
||||
App::HexSendTcpClient = set.value("HexSendTcpClient").toBool();
|
||||
App::HexReceiveTcpClient = set.value("HexReceiveTcpClient").toBool();
|
||||
App::AsciiTcpClient = set.value("AsciiTcpClient").toBool();
|
||||
App::DebugTcpClient = set.value("DebugTcpClient").toBool();
|
||||
App::AutoSendTcpClient = set.value("AutoSendTcpClient").toBool();
|
||||
App::IntervalTcpClient = set.value("IntervalTcpClient").toInt();
|
||||
App::TcpServerIP = set.value("TcpServerIP").toString();
|
||||
App::TcpServerPort = set.value("TcpServerPort").toInt();
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("TcpServerConfig");
|
||||
App::HexSendTcpServer = set.value("HexSendTcpServer").toBool();
|
||||
App::HexReceiveTcpServer = set.value("HexReceiveTcpServer").toBool();
|
||||
App::AsciiTcpServer = set.value("AsciiTcpServer").toBool();
|
||||
App::DebugTcpServer = set.value("DebugTcpServer").toBool();
|
||||
App::AutoSendTcpServer = set.value("AutoSendTcpServer").toBool();
|
||||
App::SelectAllTcpServer = set.value("SelectAllTcpServer").toBool();
|
||||
App::IntervalTcpServer = set.value("IntervalTcpServer").toInt();
|
||||
App::TcpListenPort = set.value("TcpListenPort").toInt();
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("UdpServerConfig");
|
||||
App::HexSendUdpServer = set.value("HexSendUdpServer").toBool();
|
||||
App::HexReceiveUdpServer = set.value("HexReceiveUdpServer").toBool();
|
||||
App::AsciiUdpServer = set.value("AsciiUdpServer").toBool();
|
||||
App::DebugUdpServer = set.value("DebugUdpServer").toBool();
|
||||
App::AutoSendUdpServer = set.value("AutoSendUdpServer").toBool();
|
||||
App::IntervalUdpServer = set.value("IntervalUdpServer").toInt();
|
||||
App::UdpServerIP = set.value("UdpServerIP").toString();
|
||||
App::UdpServerPort = set.value("UdpServerPort").toInt();
|
||||
App::UdpListenPort = set.value("UdpListenPort").toInt();
|
||||
set.endGroup();
|
||||
}
|
||||
|
||||
void App::writeConfig()
|
||||
{
|
||||
QSettings set(App::ConfigFile, QSettings::IniFormat);
|
||||
|
||||
set.beginGroup("AppConfig");
|
||||
set.setValue("CurrentIndex", App::CurrentIndex);
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("TcpClientConfig");
|
||||
set.setValue("HexSendTcpClient", App::HexSendTcpClient);
|
||||
set.setValue("HexReceiveTcpClient", App::HexReceiveTcpClient);
|
||||
set.setValue("DebugTcpClient", App::DebugTcpClient);
|
||||
set.setValue("AutoSendTcpClient", App::AutoSendTcpClient);
|
||||
set.setValue("IntervalTcpClient", App::IntervalTcpClient);
|
||||
set.setValue("TcpServerIP", App::TcpServerIP);
|
||||
set.setValue("TcpServerPort", App::TcpServerPort);
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("TcpServerConfig");
|
||||
set.setValue("HexSendTcpServer", App::HexSendTcpServer);
|
||||
set.setValue("HexReceiveTcpServer", App::HexReceiveTcpServer);
|
||||
set.setValue("DebugTcpServer", App::DebugTcpServer);
|
||||
set.setValue("AutoSendTcpServer", App::AutoSendTcpServer);
|
||||
set.setValue("SelectAllTcpServer", App::SelectAllTcpServer);
|
||||
set.setValue("IntervalTcpServer", App::IntervalTcpServer);
|
||||
set.setValue("TcpListenPort", App::TcpListenPort);
|
||||
set.endGroup();
|
||||
|
||||
set.beginGroup("UdpServerConfig");
|
||||
set.setValue("HexSendUdpServer", App::HexSendUdpServer);
|
||||
set.setValue("HexReceiveUdpServer", App::HexReceiveUdpServer);
|
||||
set.setValue("DebugUdpServer", App::DebugUdpServer);
|
||||
set.setValue("AutoSendUdpServer", App::AutoSendUdpServer);
|
||||
set.setValue("IntervalUdpServer", App::IntervalUdpServer);
|
||||
set.setValue("UdpServerIP", App::UdpServerIP);
|
||||
set.setValue("UdpServerPort", App::UdpServerPort);
|
||||
set.setValue("UdpListenPort", App::UdpListenPort);
|
||||
set.endGroup();
|
||||
}
|
||||
|
||||
void App::newConfig()
|
||||
{
|
||||
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
|
||||
#endif
|
||||
writeConfig();
|
||||
}
|
||||
|
||||
bool App::checkConfig()
|
||||
{
|
||||
//如果配置文件大小为0,则以初始值继续运行,并生成配置文件
|
||||
QFile file(App::ConfigFile);
|
||||
if (file.size() == 0) {
|
||||
newConfig();
|
||||
return false;
|
||||
}
|
||||
|
||||
//如果配置文件不完整,则以初始值继续运行,并生成配置文件
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
bool ok = true;
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
line = line.replace("\r", "");
|
||||
line = line.replace("\n", "");
|
||||
QStringList list = line.split("=");
|
||||
|
||||
if (list.count() == 2) {
|
||||
if (list.at(1) == "") {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
newConfig();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
newConfig();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList App::Intervals = QStringList();
|
||||
QStringList App::Datas = QStringList();
|
||||
QStringList App::Keys = QStringList();
|
||||
QStringList App::Values = QStringList();
|
||||
|
||||
void App::readSendData()
|
||||
{
|
||||
//读取发送数据列表
|
||||
App::Datas.clear();
|
||||
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(App::SendFileName);
|
||||
QFile file(fileName);
|
||||
if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) {
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
line = line.trimmed();
|
||||
line = line.replace("\r", "");
|
||||
line = line.replace("\n", "");
|
||||
if (!line.isEmpty()) {
|
||||
App::Datas.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void App::readDeviceData()
|
||||
{
|
||||
//读取转发数据列表
|
||||
App::Keys.clear();
|
||||
App::Values.clear();
|
||||
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(App::DeviceFileName);
|
||||
QFile file(fileName);
|
||||
if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) {
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
line = line.trimmed();
|
||||
line = line.replace("\r", "");
|
||||
line = line.replace("\n", "");
|
||||
if (!line.isEmpty()) {
|
||||
QStringList list = line.split(";");
|
||||
QString key = list.at(0);
|
||||
QString value;
|
||||
for (int i = 1; i < list.count(); i++) {
|
||||
value += QString("%1;").arg(list.at(i));
|
||||
}
|
||||
|
||||
//去掉末尾分号
|
||||
value = value.mid(0, value.length() - 1);
|
||||
App::Keys.append(key);
|
||||
App::Values.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
60
nettool/api/app.h
Normal file
60
nettool/api/app.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef APP_H
|
||||
#define APP_H
|
||||
|
||||
#include "head.h"
|
||||
|
||||
class App
|
||||
{
|
||||
public:
|
||||
static QString ConfigFile; //配置文件路径
|
||||
static QString SendFileName; //发送配置文件名
|
||||
static QString DeviceFileName; //模拟设备数据文件名
|
||||
|
||||
static int CurrentIndex; //当前索引
|
||||
|
||||
//TCP客户端配置参数
|
||||
static bool HexSendTcpClient; //16进制发送
|
||||
static bool HexReceiveTcpClient; //16进制接收
|
||||
static bool AsciiTcpClient; //ASCII模式
|
||||
static bool DebugTcpClient; //启用数据调试
|
||||
static bool AutoSendTcpClient; //自动发送数据
|
||||
static int IntervalTcpClient; //发送数据间隔
|
||||
static QString TcpServerIP; //服务器IP
|
||||
static int TcpServerPort; //服务器端口
|
||||
|
||||
//TCP服务器配置参数
|
||||
static bool HexSendTcpServer; //16进制发送
|
||||
static bool HexReceiveTcpServer; //16进制接收
|
||||
static bool AsciiTcpServer; //ASCII模式
|
||||
static bool DebugTcpServer; //启用数据调试
|
||||
static bool AutoSendTcpServer; //自动发送数据
|
||||
static bool SelectAllTcpServer; //选中所有
|
||||
static int IntervalTcpServer; //发送数据间隔
|
||||
static int TcpListenPort; //监听端口
|
||||
|
||||
//UDP服务器配置参数
|
||||
static bool HexSendUdpServer; //16进制发送
|
||||
static bool HexReceiveUdpServer; //16进制接收
|
||||
static bool AsciiUdpServer; //ASCII模式
|
||||
static bool DebugUdpServer; //启用数据调试
|
||||
static bool AutoSendUdpServer; //自动发送数据
|
||||
static int IntervalUdpServer; //发送数据间隔
|
||||
static QString UdpServerIP; //服务器IP
|
||||
static int UdpServerPort; //服务器端口
|
||||
static int UdpListenPort; //监听端口
|
||||
|
||||
//读写配置参数及其他操作
|
||||
static void readConfig(); //读取配置参数
|
||||
static void writeConfig(); //写入配置参数
|
||||
static void newConfig(); //以初始值新建配置文件
|
||||
static bool checkConfig(); //校验配置文件
|
||||
|
||||
static QStringList Intervals;
|
||||
static QStringList Datas;
|
||||
static QStringList Keys;
|
||||
static QStringList Values;
|
||||
static void readSendData();
|
||||
static void readDeviceData();
|
||||
};
|
||||
|
||||
#endif // APP_H
|
||||
3688
nettool/api/quiwidget.cpp
Normal file
3688
nettool/api/quiwidget.cpp
Normal file
File diff suppressed because it is too large
Load Diff
871
nettool/api/quiwidget.h
Normal file
871
nettool/api/quiwidget.h
Normal file
@@ -0,0 +1,871 @@
|
||||
#ifndef QUIWIDGET_H
|
||||
#define QUIWIDGET_H
|
||||
|
||||
#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
|
||||
#define TIME qPrintable(QTime::currentTime().toString("HH:mm:ss"))
|
||||
#define QDATE qPrintable(QDate::currentDate().toString("yyyy-MM-dd"))
|
||||
#define QTIME qPrintable(QTime::currentTime().toString("HH-mm-ss"))
|
||||
#define DATETIME qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"))
|
||||
#define STRDATETIME qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss"))
|
||||
#define STRDATETIMEMS qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss-zzz"))
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#define NEWLINE "\r\n"
|
||||
#else
|
||||
#define NEWLINE "\n"
|
||||
#endif
|
||||
|
||||
#ifdef __arm__
|
||||
#define TitleMinSize 40
|
||||
#else
|
||||
#define TitleMinSize 30
|
||||
#endif
|
||||
|
||||
/**
|
||||
* QUI无边框窗体控件 作者:feiyangqingyun(QQ:517216493)
|
||||
* 1:内置 N >= 17 套精美样式,可直接切换,也可自定义样式路径
|
||||
* 2:可设置部件(左上角图标/最小化按钮/最大化按钮/关闭按钮)的图标或者图片及是否可见
|
||||
* 3:可集成设计师插件,直接拖曳使用,所见即所得
|
||||
* 4:如果需要窗体可拖动大小,设置 setSizeGripEnabled(true);
|
||||
* 5:可设置全局样式 setStyle
|
||||
* 6:可弹出消息框,可选阻塞模式和不阻塞,默认不阻塞 showMessageBoxInfo
|
||||
* 7:可弹出错误框,可选阻塞模式和不阻塞,默认不阻塞 showMessageBoxError
|
||||
* 8:可弹出询问框 showMessageBoxError
|
||||
* 9:可弹出右下角信息框 showTipBox
|
||||
* 10:可弹出输入框 showInputBox
|
||||
* 11:可弹出时间范围选择框 showDateSelect
|
||||
* 12:消息框支持设置倒计时关闭
|
||||
* 13:集成图形字体设置方法及根据指定文字获取图片
|
||||
* 14:集成设置窗体居中显示/设置翻译文件/设置编码/设置延时/设置系统时间等静态方法
|
||||
* 15:集成获取应用程序文件名/文件路径 等方法
|
||||
*/
|
||||
|
||||
#include "head.h"
|
||||
|
||||
#ifdef quc
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
|
||||
#include <QtDesigner/QDesignerExportWidget>
|
||||
#else
|
||||
#include <QtUiPlugin/QDesignerExportWidget>
|
||||
#endif
|
||||
|
||||
class QDESIGNER_WIDGET_EXPORT QUIWidget : public QDialog
|
||||
#else
|
||||
class QUIWidget : public QDialog
|
||||
#endif
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(Style)
|
||||
Q_PROPERTY(QString title READ getTitle WRITE setTitle)
|
||||
Q_PROPERTY(Qt::Alignment alignment READ getAlignment WRITE setAlignment)
|
||||
Q_PROPERTY(bool minHide READ getMinHide WRITE setMinHide)
|
||||
Q_PROPERTY(bool exitAll READ getExitAll WRITE setExitAll)
|
||||
|
||||
public:
|
||||
//将部分对象作为枚举值暴露给外部
|
||||
enum Widget {
|
||||
Lab_Ico = 0, //左上角图标
|
||||
BtnMenu = 1, //下拉菜单按钮
|
||||
BtnMenu_Min = 2, //最小化按钮
|
||||
BtnMenu_Max = 3, //最大化按钮
|
||||
BtnMenu_Normal = 4, //还原按钮
|
||||
BtnMenu_Close = 5 //关闭按钮
|
||||
};
|
||||
|
||||
//样式枚举
|
||||
enum Style {
|
||||
Style_Silvery = 0, //银色样式
|
||||
Style_Blue = 1, //蓝色样式
|
||||
Style_LightBlue = 2, //淡蓝色样式
|
||||
Style_DarkBlue = 3, //深蓝色样式
|
||||
Style_Gray = 4, //灰色样式
|
||||
Style_LightGray = 5, //浅灰色样式
|
||||
Style_DarkGray = 6, //深灰色样式
|
||||
Style_Black = 7, //黑色样式
|
||||
Style_LightBlack = 8, //浅黑色样式
|
||||
Style_DarkBlack = 9, //深黑色样式
|
||||
Style_PSBlack = 10, //PS黑色样式
|
||||
Style_FlatBlack = 11, //黑色扁平样式
|
||||
Style_FlatWhite = 12, //白色扁平样式
|
||||
Style_FlatBlue = 13, //蓝色扁平样式
|
||||
Style_Purple = 14, //紫色样式
|
||||
Style_BlackBlue = 15, //黑蓝色样式
|
||||
Style_BlackVideo = 16 //视频监控黑色样式
|
||||
};
|
||||
|
||||
public:
|
||||
explicit QUIWidget(QWidget *parent = 0);
|
||||
~QUIWidget();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
QVBoxLayout *verticalLayout1;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout2;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout4;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout;
|
||||
QToolButton *btnMenu;
|
||||
QPushButton *btnMenu_Min;
|
||||
QPushButton *btnMenu_Max;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widget;
|
||||
QVBoxLayout *verticalLayout3;
|
||||
|
||||
private:
|
||||
QString title; //标题
|
||||
Qt::Alignment alignment; //标题文本对齐
|
||||
bool minHide; //最小化隐藏
|
||||
bool exitAll; //退出整个程序
|
||||
QWidget *mainWidget; //主窗体对象
|
||||
|
||||
public:
|
||||
QLabel *getLabIco() const;
|
||||
QLabel *getLabTitle() const;
|
||||
QToolButton *getBtnMenu() const;
|
||||
QPushButton *getBtnMenuMin() const;
|
||||
QPushButton *getBtnMenuMax() const;
|
||||
QPushButton *getBtnMenuMClose() const;
|
||||
|
||||
QString getTitle() const;
|
||||
Qt::Alignment getAlignment() const;
|
||||
bool getMinHide() const;
|
||||
bool getExitAll() const;
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
void changeStyle(); //更换样式
|
||||
|
||||
private slots:
|
||||
void on_btnMenu_Min_clicked();
|
||||
void on_btnMenu_Max_clicked();
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置部件图标
|
||||
void setIcon(QUIWidget::Widget widget, const QChar &str, quint32 size = 12);
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
//设置部件图片
|
||||
void setPixmap(QUIWidget::Widget widget, const QString &file, const QSize &size = QSize(16, 16));
|
||||
//设置部件是否可见
|
||||
void setVisible(QUIWidget::Widget widget, bool visible = true);
|
||||
//设置只有关闭按钮
|
||||
void setOnlyCloseBtn();
|
||||
|
||||
//设置标题栏高度
|
||||
void setTitleHeight(int height);
|
||||
//设置按钮统一宽度
|
||||
void setBtnWidth(int width);
|
||||
|
||||
//设置标题及文本样式
|
||||
void setTitle(const QString &title);
|
||||
void setAlignment(Qt::Alignment alignment);
|
||||
|
||||
//设置最小化隐藏
|
||||
void setMinHide(bool minHide);
|
||||
|
||||
//设置退出时候直接退出整个应用程序
|
||||
void setExitAll(bool exitAll);
|
||||
|
||||
//设置主窗体
|
||||
void setMainWidget(QWidget *mainWidget);
|
||||
|
||||
Q_SIGNALS:
|
||||
void changeStyle(const QString &qssFile);
|
||||
void closing();
|
||||
};
|
||||
|
||||
//弹出信息框类
|
||||
class QUIMessageBox : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUIMessageBox *Instance();
|
||||
explicit QUIMessageBox(QWidget *parent = 0);
|
||||
~QUIMessageBox();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<QUIMessageBox> self;
|
||||
|
||||
QVBoxLayout *verticalLayout1;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout3;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QLabel *labTime;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout4;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout2;
|
||||
QFrame *frame;
|
||||
QVBoxLayout *verticalLayout4;
|
||||
QHBoxLayout *horizontalLayout1;
|
||||
QLabel *labIcoMain;
|
||||
QSpacerItem *horizontalSpacer1;
|
||||
QLabel *labInfo;
|
||||
QHBoxLayout *horizontalLayout2;
|
||||
QSpacerItem *horizontalSpacer2;
|
||||
QPushButton *btnOk;
|
||||
QPushButton *btnCancel;
|
||||
|
||||
private:
|
||||
int closeSec; //总显示时间
|
||||
int currentSec; //当前已显示时间
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
void checkSec(); //校验倒计时
|
||||
|
||||
private slots:
|
||||
void on_btnOk_clicked();
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
void setMessage(const QString &msg, int type, int closeSec = 0);
|
||||
};
|
||||
|
||||
//右下角弹出框类
|
||||
class QUITipBox : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUITipBox *Instance();
|
||||
explicit QUITipBox(QWidget *parent = 0);
|
||||
~QUITipBox();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *);
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<QUITipBox> self;
|
||||
|
||||
QVBoxLayout *verticalLayout;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout2;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QLabel *labTime;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout2;
|
||||
QLabel *labInfo;
|
||||
|
||||
QPropertyAnimation *animation;
|
||||
bool fullScreen;
|
||||
|
||||
private:
|
||||
int closeSec; //总显示时间
|
||||
int currentSec; //当前已显示时间
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
void checkSec(); //校验倒计时
|
||||
|
||||
private slots:
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
void setTip(const QString &title, const QString &tip, bool fullScreen = false, bool center = true, int closeSec = 0);
|
||||
void hide();
|
||||
};
|
||||
|
||||
|
||||
//弹出输入框类
|
||||
class QUIInputBox : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUIInputBox *Instance();
|
||||
explicit QUIInputBox(QWidget *parent = 0);
|
||||
~QUIInputBox();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *);
|
||||
void closeEvent(QCloseEvent *);
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<QUIInputBox> self;
|
||||
|
||||
QVBoxLayout *verticalLayout1;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout1;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QLabel *labTime;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout2;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout2;
|
||||
QFrame *frame;
|
||||
QVBoxLayout *verticalLayout3;
|
||||
QLabel *labInfo;
|
||||
QLineEdit *txtValue;
|
||||
QComboBox *cboxValue;
|
||||
QHBoxLayout *lay;
|
||||
QSpacerItem *horizontalSpacer;
|
||||
QPushButton *btnOk;
|
||||
QPushButton *btnCancel;
|
||||
|
||||
private:
|
||||
int closeSec; //总显示时间
|
||||
int currentSec; //当前已显示时间
|
||||
QString value; //当前值
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
void checkSec(); //校验倒计时
|
||||
|
||||
private slots:
|
||||
void on_btnOk_clicked();
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public:
|
||||
QString getValue()const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
void setParameter(const QString &title, int type = 0, int closeSec = 0,
|
||||
QString placeholderText = QString(), bool pwd = false,
|
||||
const QString &defaultValue = QString());
|
||||
|
||||
};
|
||||
|
||||
//弹出日期选择对话框
|
||||
class QUIDateSelect : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUIDateSelect *Instance();
|
||||
explicit QUIDateSelect(QWidget *parent = 0);
|
||||
~QUIDateSelect();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<QUIDateSelect> self;
|
||||
|
||||
QVBoxLayout *verticalLayout;
|
||||
QWidget *widgetTitle;
|
||||
QHBoxLayout *horizontalLayout1;
|
||||
QLabel *labIco;
|
||||
QLabel *labTitle;
|
||||
QWidget *widgetMenu;
|
||||
QHBoxLayout *horizontalLayout;
|
||||
QPushButton *btnMenu_Close;
|
||||
QWidget *widgetMain;
|
||||
QVBoxLayout *verticalLayout1;
|
||||
QFrame *frame;
|
||||
QGridLayout *gridLayout;
|
||||
QLabel *labStart;
|
||||
QPushButton *btnOk;
|
||||
QLabel *labEnd;
|
||||
QPushButton *btnClose;
|
||||
QDateTimeEdit *dateStart;
|
||||
QDateTimeEdit *dateEnd;
|
||||
|
||||
private:
|
||||
QString startDateTime; //开始时间
|
||||
QString endDateTime; //结束时间
|
||||
QString format; //日期时间格式
|
||||
|
||||
private slots:
|
||||
void initControl(); //初始化控件
|
||||
void initForm(); //初始化窗体
|
||||
|
||||
private slots:
|
||||
void on_btnOk_clicked();
|
||||
void on_btnMenu_Close_clicked();
|
||||
|
||||
public:
|
||||
//获取当前选择的开始时间和结束时间
|
||||
QString getStartDateTime() const;
|
||||
QString getEndDateTime() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setIconMain(const QChar &str, quint32 size = 12);
|
||||
void setFormat(const QString &format);
|
||||
|
||||
};
|
||||
|
||||
//图形字体处理类
|
||||
class IconHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static IconHelper *Instance();
|
||||
explicit IconHelper(QObject *parent = 0);
|
||||
|
||||
//获取图形字体
|
||||
QFont getIconFont();
|
||||
|
||||
//设置图形字体到标签
|
||||
void setIcon(QLabel *lab, const QChar &str, quint32 size = 12);
|
||||
//设置图形字体到按钮
|
||||
void setIcon(QAbstractButton *btn, const QChar &str, quint32 size = 12);
|
||||
|
||||
//获取指定图形字体,可以指定文字大小,图片宽高,文字对齐
|
||||
QPixmap getPixmap(const QColor &color, const QChar &str, quint32 size = 12,
|
||||
quint32 pixWidth = 15, quint32 pixHeight = 15,
|
||||
int flags = Qt::AlignCenter);
|
||||
|
||||
//根据按钮获取该按钮对应的图标
|
||||
QPixmap getPixmap(QToolButton *btn, bool normal);
|
||||
QPixmap getPixmap(QToolButton *btn, int type);
|
||||
|
||||
//指定QFrame导航按钮样式,带图标
|
||||
void setStyle(QFrame *frame, QList<QToolButton *> btns, QList<int> pixChar,
|
||||
quint32 iconSize = 12, quint32 iconWidth = 15, quint32 iconHeight = 15,
|
||||
const QString &normalBgColor = "#2FC5A2",
|
||||
const QString &darkBgColor = "#3EA7E9",
|
||||
const QString &normalTextColor = "#EEEEEE",
|
||||
const QString &darkTextColor = "#FFFFFF");
|
||||
|
||||
//指定导航面板样式,不带图标
|
||||
static void setStyle(QWidget *widget, const QString &type = "left", int borderWidth = 3,
|
||||
const QString &borderColor = "#029FEA",
|
||||
const QString &normalBgColor = "#292F38",
|
||||
const QString &darkBgColor = "#1D2025",
|
||||
const QString &normalTextColor = "#54626F",
|
||||
const QString &darkTextColor = "#FDFDFD");
|
||||
|
||||
//移除导航面板样式,防止重复
|
||||
void removeStyle(QList<QToolButton *> btns);
|
||||
|
||||
//指定QWidget导航面板样式,带图标和效果切换
|
||||
void setStyle(QWidget *widget, QList<QToolButton *> btns, QList<int> pixChar,
|
||||
quint32 iconSize = 12, quint32 iconWidth = 15, quint32 iconHeight = 15,
|
||||
const QString &type = "left", int borderWidth = 3,
|
||||
const QString &borderColor = "#029FEA",
|
||||
const QString &normalBgColor = "#292F38",
|
||||
const QString &darkBgColor = "#1D2025",
|
||||
const QString &normalTextColor = "#54626F",
|
||||
const QString &darkTextColor = "#FDFDFD");
|
||||
|
||||
struct StyleColor {
|
||||
quint32 iconSize;
|
||||
quint32 iconWidth;
|
||||
quint32 iconHeight;
|
||||
quint32 borderWidth;
|
||||
QString type;
|
||||
QString borderColor;
|
||||
QString normalBgColor;
|
||||
QString normalTextColor;
|
||||
QString hoverBgColor;
|
||||
QString hoverTextColor;
|
||||
QString pressedBgColor;
|
||||
QString pressedTextColor;
|
||||
QString checkedBgColor;
|
||||
QString checkedTextColor;
|
||||
|
||||
StyleColor()
|
||||
{
|
||||
iconSize = 12;
|
||||
iconWidth = 15;
|
||||
iconHeight = 15;
|
||||
borderWidth = 3;
|
||||
type = "left";
|
||||
borderColor = "#029FEA";
|
||||
normalBgColor = "#292F38";
|
||||
normalTextColor = "#54626F";
|
||||
hoverBgColor = "#40444D";
|
||||
hoverTextColor = "#FDFDFD";
|
||||
pressedBgColor = "#404244";
|
||||
pressedTextColor = "#FDFDFD";
|
||||
checkedBgColor = "#44494F";
|
||||
checkedTextColor = "#FDFDFD";
|
||||
}
|
||||
};
|
||||
|
||||
//指定QWidget导航面板样式,带图标和效果切换+悬停颜色+按下颜色+选中颜色
|
||||
void setStyle(QWidget *widget, QList<QToolButton *> btns, QList<int> pixChar, const StyleColor &styleColor);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
static QScopedPointer<IconHelper> self;
|
||||
|
||||
QFont iconFont; //图形字体
|
||||
QList<QToolButton *> btns; //按钮队列
|
||||
QList<QPixmap> pixNormal; //正常图片队列
|
||||
QList<QPixmap> pixDark; //加深图片队列
|
||||
QList<QPixmap> pixHover; //悬停图片队列
|
||||
QList<QPixmap> pixPressed; //按下图片队列
|
||||
QList<QPixmap> pixChecked; //选中图片队列
|
||||
};
|
||||
|
||||
//托盘图标类
|
||||
class TrayIcon : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static TrayIcon *Instance();
|
||||
explicit TrayIcon(QObject *parent = 0);
|
||||
|
||||
private:
|
||||
static QScopedPointer<TrayIcon> self;
|
||||
|
||||
QWidget *mainWidget; //对应所属主窗体
|
||||
QSystemTrayIcon *trayIcon; //托盘对象
|
||||
QMenu *menu; //右键菜单
|
||||
bool exitDirect; //是否直接退出
|
||||
|
||||
private slots:
|
||||
void iconIsActived(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
public Q_SLOTS:
|
||||
//设置是否直接退出,如果不是直接退出则发送信号给主界面
|
||||
void setExitDirect(bool exitDirect);
|
||||
|
||||
//设置所属主窗体
|
||||
void setMainWidget(QWidget *mainWidget);
|
||||
|
||||
//显示消息
|
||||
void showMessage(const QString &title, const QString &msg,
|
||||
QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int msecs = 5000);
|
||||
|
||||
//设置图标
|
||||
void setIcon(const QString &strIcon);
|
||||
//设置提示信息
|
||||
void setToolTip(const QString &tip);
|
||||
//设置是否可见
|
||||
void setVisible(bool visible);
|
||||
//退出所有
|
||||
void closeAll();
|
||||
|
||||
Q_SIGNALS:
|
||||
void trayIconExit();
|
||||
};
|
||||
|
||||
|
||||
//全局静态方法类
|
||||
class QUIHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
//桌面宽度高度
|
||||
static int deskWidth();
|
||||
static int deskHeight();
|
||||
|
||||
//程序本身文件名称
|
||||
static QString appName();
|
||||
//程序当前所在路径
|
||||
static QString appPath();
|
||||
|
||||
//初始化随机数种子
|
||||
static void initRand();
|
||||
|
||||
//初始化数据库
|
||||
static void initDb(const QString &dbName);
|
||||
//初始化文件,不存在则拷贝
|
||||
static void initFile(const QString &sourceName, const QString &targetName);
|
||||
|
||||
//新建目录
|
||||
static void newDir(const QString &dirName);
|
||||
|
||||
//写入消息到额外的的消息日志文件
|
||||
static void writeInfo(const QString &info, const QString &filePath = "log");
|
||||
static void writeError(const QString &info, const QString &filePath = "log");
|
||||
|
||||
//设置全局样式
|
||||
static void setStyle(QUIWidget::Style style);
|
||||
static void setStyle(const QString &qssFile, QString &paletteColor, QString &textColor);
|
||||
static void setStyle(const QString &qssFile, QString &textColor,
|
||||
QString &panelColor, QString &borderColor,
|
||||
QString &normalColorStart, QString &normalColorEnd,
|
||||
QString &darkColorStart, QString &darkColorEnd,
|
||||
QString &highColor);
|
||||
|
||||
//根据QSS样式获取对应颜色值
|
||||
static void getQssColor(const QString &qss, QString &textColor,
|
||||
QString &panelColor, QString &borderColor,
|
||||
QString &normalColorStart, QString &normalColorEnd,
|
||||
QString &darkColorStart, QString &darkColorEnd,
|
||||
QString &highColor);
|
||||
|
||||
//九宫格图片 horzSplit-宫格1/3/7/9宽度 vertSplit-宫格1/3/7/9高度 dstWidth-目标图片宽度 dstHeight-目标图片高度
|
||||
static QPixmap ninePatch(const QString &picName, int horzSplit, int vertSplit, int dstWidth, int dstHeight);
|
||||
static QPixmap ninePatch(const QPixmap &pix, int horzSplit, int vertSplit, int dstWidth, int dstHeight);
|
||||
|
||||
//设置标签颜色
|
||||
static void setLabStyle(QLabel *lab, quint8 type);
|
||||
|
||||
//设置窗体居中显示
|
||||
static void setFormInCenter(QWidget *frm);
|
||||
//设置翻译文件
|
||||
static void setTranslator(const QString &qmFile = ":/image/qt_zh_CN.qm");
|
||||
//设置编码
|
||||
static void setCode();
|
||||
//设置延时
|
||||
static void sleep(int msec);
|
||||
//设置系统时间
|
||||
static void setSystemDateTime(const QString &year, const QString &month, const QString &day,
|
||||
const QString &hour, const QString &min, const QString &sec);
|
||||
//设置开机自启动
|
||||
static void runWithSystem(const QString &strName, const QString &strPath, bool autoRun = true);
|
||||
|
||||
//判断是否是IP地址
|
||||
static bool isIP(const QString &ip);
|
||||
|
||||
//判断是否是MAC地址
|
||||
static bool isMac(const QString &mac);
|
||||
|
||||
//判断是否是合法的电话号码
|
||||
static bool isTel(const QString &tel);
|
||||
|
||||
//判断是否是合法的邮箱地址
|
||||
static bool isEmail(const QString &email);
|
||||
|
||||
|
||||
//16进制字符串转10进制
|
||||
static int strHexToDecimal(const QString &strHex);
|
||||
|
||||
//10进制字符串转10进制
|
||||
static int strDecimalToDecimal(const QString &strDecimal);
|
||||
|
||||
//2进制字符串转10进制
|
||||
static int strBinToDecimal(const QString &strBin);
|
||||
|
||||
//16进制字符串转2进制字符串
|
||||
static QString strHexToStrBin(const QString &strHex);
|
||||
|
||||
//10进制转2进制字符串一个字节
|
||||
static QString decimalToStrBin1(int decimal);
|
||||
|
||||
//10进制转2进制字符串两个字节
|
||||
static QString decimalToStrBin2(int decimal);
|
||||
|
||||
//10进制转16进制字符串,补零.
|
||||
static QString decimalToStrHex(int decimal);
|
||||
|
||||
|
||||
//int转字节数组
|
||||
static QByteArray intToByte(int i);
|
||||
static QByteArray intToByteRec(int i);
|
||||
|
||||
//字节数组转int
|
||||
static int byteToInt(const QByteArray &data);
|
||||
static int byteToIntRec(const QByteArray &data);
|
||||
static quint32 byteToUInt(const QByteArray &data);
|
||||
static quint32 byteToUIntRec(const QByteArray &data);
|
||||
|
||||
//ushort转字节数组
|
||||
static QByteArray ushortToByte(ushort i);
|
||||
static QByteArray ushortToByteRec(ushort i);
|
||||
|
||||
//字节数组转ushort
|
||||
static int byteToUShort(const QByteArray &data);
|
||||
static int byteToUShortRec(const QByteArray &data);
|
||||
|
||||
//异或加密算法
|
||||
static QString getXorEncryptDecrypt(const QString &str, char key);
|
||||
|
||||
//异或校验
|
||||
static uchar getOrCode(const QByteArray &data);
|
||||
|
||||
//计算校验码
|
||||
static uchar getCheckCode(const QByteArray &data);
|
||||
|
||||
//字符串补全
|
||||
static QString getValue(quint8 value);
|
||||
|
||||
//CRC校验
|
||||
static quint16 getRevCrc_16(quint8 *data, int len, quint16 init, const quint16 *table);
|
||||
static quint16 getCrc_16(quint8 *data, int len, quint16 init, const quint16 *table);
|
||||
static quint16 getModbus16(quint8 *data, int len);
|
||||
static QByteArray getCRCCode(const QByteArray &data);
|
||||
|
||||
|
||||
//字节数组转Ascii字符串
|
||||
static QString byteArrayToAsciiStr(const QByteArray &data);
|
||||
|
||||
//16进制字符串转字节数组
|
||||
static QByteArray hexStrToByteArray(const QString &str);
|
||||
static char convertHexChar(char ch);
|
||||
|
||||
//Ascii字符串转字节数组
|
||||
static QByteArray asciiStrToByteArray(const QString &str);
|
||||
|
||||
//字节数组转16进制字符串
|
||||
static QString byteArrayToHexStr(const QByteArray &data);
|
||||
|
||||
//获取保存的文件
|
||||
static QString getSaveName(const QString &filter, QString defaultDir = QCoreApplication::applicationDirPath());
|
||||
|
||||
//获取选择的文件
|
||||
static QString getFileName(const QString &filter, QString defaultDir = QCoreApplication::applicationDirPath());
|
||||
|
||||
//获取选择的文件集合
|
||||
static QStringList getFileNames(const QString &filter, QString defaultDir = QCoreApplication::applicationDirPath());
|
||||
|
||||
//获取选择的目录
|
||||
static QString getFolderName();
|
||||
|
||||
//获取文件名,含拓展名
|
||||
static QString getFileNameWithExtension(const QString &strFilePath);
|
||||
|
||||
//获取选择文件夹中的文件
|
||||
static QStringList getFolderFileNames(const QStringList &filter);
|
||||
|
||||
//文件夹是否存在
|
||||
static bool folderIsExist(const QString &strFolder);
|
||||
|
||||
//文件是否存在
|
||||
static bool fileIsExist(const QString &strFile);
|
||||
|
||||
//复制文件
|
||||
static bool copyFile(const QString &sourceFile, const QString &targetFile);
|
||||
|
||||
//删除文件夹下所有文件
|
||||
static void deleteDirectory(const QString &path);
|
||||
|
||||
//判断IP地址及端口是否在线
|
||||
static bool ipLive(const QString &ip, int port, int timeout = 1000);
|
||||
|
||||
//获取网页所有源代码
|
||||
static QString getHtml(const QString &url);
|
||||
|
||||
//获取本机公网IP地址
|
||||
static QString getNetIP(const QString &webCode);
|
||||
|
||||
//获取本机IP
|
||||
static QString getLocalIP();
|
||||
|
||||
//Url地址转为IP地址
|
||||
static QString urlToIP(const QString &url);
|
||||
|
||||
//判断是否通外网
|
||||
static bool isWebOk();
|
||||
|
||||
|
||||
//弹出消息框
|
||||
static void showMessageBoxInfo(const QString &info, int closeSec = 0, bool exec = false);
|
||||
//弹出错误框
|
||||
static void showMessageBoxError(const QString &info, int closeSec = 0, bool exec = false);
|
||||
//弹出询问框
|
||||
static int showMessageBoxQuestion(const QString &info);
|
||||
|
||||
//弹出+隐藏右下角信息框
|
||||
static void showTipBox(const QString &title, const QString &tip, bool fullScreen = false,
|
||||
bool center = true, int closeSec = 0);
|
||||
static void hideTipBox();
|
||||
|
||||
//弹出输入框
|
||||
static QString showInputBox(const QString &title, int type = 0, int closeSec = 0,
|
||||
const QString &placeholderText = QString(), bool pwd = false,
|
||||
const QString &defaultValue = QString());
|
||||
|
||||
//弹出日期选择框
|
||||
static void showDateSelect(QString &dateStart, QString &dateEnd, const QString &format = "yyyy-MM-dd");
|
||||
|
||||
|
||||
//设置按钮样式
|
||||
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 setProgressBarQss(QProgressBar *bar,
|
||||
int barHeight = 8, //进度条高度
|
||||
int barRadius = 5, //进度条半径
|
||||
int fontSize = 9, //文字字号
|
||||
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", //指示器颜色
|
||||
const QString &textColor = "#000000"); //文字颜色
|
||||
|
||||
//设置单选框样式
|
||||
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"); //指示器按下颜色
|
||||
};
|
||||
|
||||
//全局变量控制
|
||||
class QUIConfig
|
||||
{
|
||||
public:
|
||||
//全局图标
|
||||
static QChar IconMain; //标题栏左上角图标
|
||||
static QChar IconMenu; //下拉菜单图标
|
||||
static QChar IconMin; //最小化图标
|
||||
static QChar IconMax; //最大化图标
|
||||
static QChar IconNormal; //还原图标
|
||||
static QChar IconClose; //关闭图标
|
||||
|
||||
static QString FontName; //全局字体名称
|
||||
static int FontSize; //全局字体大小
|
||||
|
||||
//样式表颜色值
|
||||
static QString TextColor; //文字颜色
|
||||
static QString PanelColor; //面板颜色
|
||||
static QString BorderColor; //边框颜色
|
||||
static QString NormalColorStart;//正常状态开始颜色
|
||||
static QString NormalColorEnd; //正常状态结束颜色
|
||||
static QString DarkColorStart; //加深状态开始颜色
|
||||
static QString DarkColorEnd; //加深状态结束颜色
|
||||
static QString HighColor; //高亮颜色
|
||||
};
|
||||
|
||||
#endif // QUIWIDGET_H
|
||||
163
nettool/api/tcpserver.cpp
Normal file
163
nettool/api/tcpserver.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#include "tcpserver.h"
|
||||
#include "quiwidget.h"
|
||||
|
||||
TcpClient::TcpClient(QObject *parent) : QTcpSocket(parent)
|
||||
{
|
||||
ip = "127.0.0.1";
|
||||
port = 6000;
|
||||
|
||||
connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(deleteLater()));
|
||||
connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
|
||||
connect(this, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
}
|
||||
|
||||
void TcpClient::setIP(const QString &ip)
|
||||
{
|
||||
this->ip = ip;
|
||||
}
|
||||
|
||||
QString TcpClient::getIP() const
|
||||
{
|
||||
return this->ip;
|
||||
}
|
||||
|
||||
void TcpClient::setPort(int port)
|
||||
{
|
||||
this->port = port;
|
||||
}
|
||||
|
||||
int TcpClient::getPort() const
|
||||
{
|
||||
return this->port;
|
||||
}
|
||||
|
||||
void TcpClient::readData()
|
||||
{
|
||||
QByteArray data = this->readAll();
|
||||
if (data.length() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString buffer;
|
||||
if (App::HexReceiveTcpServer) {
|
||||
buffer = QUIHelper::byteArrayToHexStr(data);
|
||||
} else if (App::AsciiTcpServer) {
|
||||
buffer = QUIHelper::byteArrayToAsciiStr(data);
|
||||
} else {
|
||||
buffer = QString(data);
|
||||
}
|
||||
|
||||
emit receiveData(ip, port, buffer);
|
||||
|
||||
//自动回复数据,可以回复的数据是以;隔开,每行可以带多个;所以这里不需要继续判断
|
||||
if (App::DebugTcpServer) {
|
||||
int count = App::Keys.count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (App::Keys.at(i) == buffer) {
|
||||
sendData(App::Values.at(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TcpClient::sendData(const QString &data)
|
||||
{
|
||||
QByteArray buffer;
|
||||
if (App::HexSendTcpServer) {
|
||||
buffer = QUIHelper::hexStrToByteArray(data);
|
||||
} else if (App::AsciiTcpServer) {
|
||||
buffer = QUIHelper::asciiStrToByteArray(data);
|
||||
} else {
|
||||
buffer = data.toLatin1();
|
||||
}
|
||||
|
||||
this->write(buffer);
|
||||
emit sendData(ip, port, data);
|
||||
}
|
||||
|
||||
TcpServer::TcpServer(QObject *parent) : QTcpServer(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void TcpServer::incomingConnection(int handle)
|
||||
{
|
||||
TcpClient *client = new TcpClient(this);
|
||||
client->setSocketDescriptor(handle);
|
||||
connect(client, SIGNAL(disconnected()), this, SLOT(disconnected()));
|
||||
connect(client, SIGNAL(sendData(QString, int, QString)), this, SIGNAL(sendData(QString, int, QString)));
|
||||
connect(client, SIGNAL(receiveData(QString, int, QString)), this, SIGNAL(receiveData(QString, int, QString)));
|
||||
|
||||
QString ip = client->peerAddress().toString();
|
||||
int port = client->peerPort();
|
||||
client->setIP(ip);
|
||||
client->setPort(port);
|
||||
emit clientConnected(ip, port);
|
||||
emit sendData(ip, port, "客户端上线");
|
||||
|
||||
//连接后加入链表
|
||||
clients.append(client);
|
||||
}
|
||||
|
||||
void TcpServer::disconnected()
|
||||
{
|
||||
TcpClient *client = (TcpClient *)sender();
|
||||
QString ip = client->getIP();
|
||||
int port = client->getPort();
|
||||
emit clientDisconnected(ip, port);
|
||||
emit sendData(ip, port, "客户端下线");
|
||||
|
||||
//断开连接后从链表中移除
|
||||
clients.removeOne(client);
|
||||
}
|
||||
|
||||
bool TcpServer::start()
|
||||
{
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
|
||||
bool ok = listen(QHostAddress::AnyIPv4, App::TcpListenPort);
|
||||
#else
|
||||
bool ok = listen(QHostAddress::Any, App::TcpListenPort);
|
||||
#endif
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void TcpServer::stop()
|
||||
{
|
||||
remove();
|
||||
this->close();
|
||||
}
|
||||
|
||||
void TcpServer::writeData(const QString &ip, int port, const QString &data)
|
||||
{
|
||||
foreach (TcpClient *client, clients) {
|
||||
if (client->peerAddress().toString() == ip && client->peerPort() == port) {
|
||||
client->sendData(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TcpServer::writeData(const QString &data)
|
||||
{
|
||||
foreach (TcpClient *client, clients) {
|
||||
client->sendData(data);
|
||||
}
|
||||
}
|
||||
|
||||
void TcpServer::remove(const QString &ip, int port)
|
||||
{
|
||||
foreach (TcpClient *client, clients) {
|
||||
if (client->peerAddress().toString() == ip && client->peerPort() == port) {
|
||||
client->disconnectFromHost();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TcpServer::remove()
|
||||
{
|
||||
foreach (TcpClient *client, clients) {
|
||||
client->disconnectFromHost();
|
||||
}
|
||||
}
|
||||
75
nettool/api/tcpserver.h
Normal file
75
nettool/api/tcpserver.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef TCPSERVER_H
|
||||
#define TCPSERVER_H
|
||||
|
||||
#include <QtNetwork>
|
||||
|
||||
class TcpClient : public QTcpSocket
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TcpClient(QObject *parent = 0);
|
||||
|
||||
private:
|
||||
QString ip;
|
||||
int port;
|
||||
|
||||
public:
|
||||
void setIP(const QString &ip);
|
||||
QString getIP()const;
|
||||
|
||||
void setPort(int port);
|
||||
int getPort()const;
|
||||
|
||||
private slots:
|
||||
void readData();
|
||||
|
||||
signals:
|
||||
void sendData(const QString &ip, int port, const QString &data);
|
||||
void receiveData(const QString &ip, int port, const QString &data);
|
||||
|
||||
public slots:
|
||||
void sendData(const QString &data);
|
||||
|
||||
};
|
||||
|
||||
class TcpServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TcpServer(QObject *parent = 0);
|
||||
|
||||
private:
|
||||
QList<TcpClient *> clients;
|
||||
|
||||
protected:
|
||||
void incomingConnection(int handle);
|
||||
|
||||
private slots:
|
||||
void disconnected();
|
||||
|
||||
signals:
|
||||
void sendData(const QString &ip, int port, const QString &data);
|
||||
void receiveData(const QString &ip, int port, const QString &data);
|
||||
|
||||
void clientConnected(const QString &ip, int port);
|
||||
void clientDisconnected(const QString &ip, int port);
|
||||
|
||||
public slots:
|
||||
//启动服务
|
||||
bool start();
|
||||
//停止服务
|
||||
void stop();
|
||||
|
||||
//指定连接发送数据
|
||||
void writeData(const QString &ip, int port, const QString &data);
|
||||
//对所有连接发送数据
|
||||
void writeData(const QString &data);
|
||||
|
||||
//断开指定连接
|
||||
void remove(const QString &ip, int port);
|
||||
//断开所有连接
|
||||
void remove();
|
||||
|
||||
};
|
||||
|
||||
#endif // TCPSERVER_H
|
||||
20
nettool/file/device.txt
Normal file
20
nettool/file/device.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
2015;\NUL2015
|
||||
666;667
|
||||
3001P;301PST1:hehe'2:P2'3:P3'
|
||||
3002P;301PST
|
||||
3003P;301PST
|
||||
3004P;301PST
|
||||
3005P;301PST
|
||||
326;00110
|
||||
320;00101
|
||||
330010;00101
|
||||
331;332001
|
||||
568X;5691:0
|
||||
5700;5710:10:1;2;3
|
||||
330051;00101
|
||||
112P001000I1';113P001100I1'101I1'102B0'103B0'106B0'107I0'108I1'109I0'110R1.750000'111R6.300000'112R1.500000'113R3.100000'114R4.500000'115R1.050000'116R7.000000'117R9999.000000'118I0'119R3.500000'120R1.750000'121I1'122I0'123I0'124I70'130I1000'131I8000'132I1500'133I10000'134I10'135I5'136I20'137I40'140R0.000000'105B1'138I700'104I0'125I0'126I9999'141R0.200000'142R0.200000'143R0.000000'144R30.000000'150I1'151I10'152B0'153I0'160I0'200B0'210B0'211I1'212I1'213R1.050000'214R9999.000000'220B0'221I0'222I1'223I1'224R1.050000'225R7.000000'230B0'240I0'241B1'242B0'243B0'244B0'245R100.000000'246B0'260R0.000000'261I0'262I0'263I50'264I0'280B0'281R1.050000'282I9999'283I1'284R7.000000'285I1'286I1'290I0'291R9999.000000'292R9999.000000'293I10'294I150'295I0'402Shehe'406I1433082933'500R0.000000'501R9999.000000'502I4'503I10'504I1'505I30'506B0'510R0.000000'511R9999.000000'512R0.000000'513R9999.000000'514R0.000000'515R0.000000'507B0'520I0'521I9999'522I0'523I9999'524I0'525I0'508B0'560R0.000000'561R9999.000000'562R0.000000'563R9999.000000'564R0.000000'565R0.000000'530I0'531I9999'532I0'533I9999'534I0'535I0'540R0.000000'541R9999.000000'542R0.000000'543R9999.000000'544R0.000000'545R0.000000'550R0.000000'551R9999.000000'552R0.000000'553R9999.000000'554R0.000000'555R0.000000'
|
||||
302P001;00101
|
||||
002;003\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL
|
||||
112R000;113R001100R2.530000'101I1'102I23'103I1'104I0'105I0'106I3'107B1'108I0'109I2'110R0.000000'111I1'116R0.000000'117R0.000000'118I1'120I0'121I1'122R0.000000'123I1'300I186'301S2015-06-01'302S15:53:56'303S'305S359194'311I0'312I0'313I0'314I1'319I0'340I1'341I0'351SGUT'360S'361S'362S'
|
||||
126;123G100I00186'101S2015-06-01'102S15:53:56'103S'104S0'105S359194'106I00000'107I00000'110I00000'111I00000'112I00000'113I00000'114I00001'115I00000'116I00000'200I00003'201R00001.50'202I00000'203I01060'204I1638400'205I00001'206R00002.50'210R00002.20'211R00002.80'212R00000.00'213R00000.00'214R00000.42'215R09999.00'216R00000.42'217R00002.80'218R00000.00'219R00000.00'230R00000.42'231R00002.80'232R00002.53';\ETX\xA6\EOT]\ENQI\ACK{\x08\ETX\x07\xB0\ENQ\xEA\NUL\xD8\xFF\x9F\xFF\x7F\xFF\xC3\xFF\xFC\xFF\x10\xFF\xC1\NUL\EOT\xFF\xFC\NUL\CR\SOH\CR\SOH\xB4\SOH\xC2\SOH\xC8\SOH\xC8\SOH\xA6\SOH\x94\SOH\xA8\SOH\xC6\SOH\xD8\SOH\xDC\SOH\xDA\SOH\xD8\SOH\xDA\SOH\xDA\SOH\xDC\SOH\xDC\SOH\xE4\SOH\xEC\SOH\xF4\STX\NUL\STX\LF\STX\x12\STX\x12\STX\x16\STX\x14\STX\x10\STX\x08\SOH\xE8\SOH\x98\SOH-\NUL\xE1\NUL\xA2\NUL\x86\NUL\x86\NUL\x96\NUL\xA8\NUL\xBF\NUL\xDD\NUL\xFF\SOH\x1D\SOH?\SOH_\SOHz\SOH\x98\SOH\xB4\SOH\xCC\SOH\xE4\SOH\xFA\STX\NUL\STX\ACK\STX\x08\STX\x0C\STX\ACK\STX\STX\SOH\xFE\SOH\xF6\SOH\xF4\SOH\xF6\SOH\xFA\STX\STX\STX\x0E\STX\x16\STX\x19\STX\x19\STX\ESC\STX\x1F\STX\x1F\STX\ESC\STX\x14\STX\x12\STX\x16\STX\ESC\STX%\STX3\STXA\STXC\STXG\STXM\STXO\STXO\STXO\STXO\STXO\STXU\STXU\STX]\STXe\STXq\STXw\STXy\STX\x7F\STX\x7F\STX\x81\STX\x85\STX\x83\STX\x83\STX\x87\STX\x8B\STX\x95\STX\xA7\STX\xBB\STX\xCE\STX\xD8\STX\xE6\STX\xF8\ETX\x10\ETX$\ETX:\ETXP\ETXn\ETX\x8F\ETX\xB3\ETX\xDD\EOT\x07\EOT+\EOTN\EOTh\EOT\x84\EOT\xA0\EOT\xBA\EOT\xD4\EOT\xE7\EOT\xF9\ENQ\x0F\ENQ)\ENQG\ENQi\ENQ\x95\ENQ\xB4\ENQ\xD0\ENQ\xEC\ACK\x0C\ACK(\ACKF\ACK[\ACKm\ACK}\ACK\x93\ACK\xA3\ACK\xBD\ACK\xDD\x07\STX\x07"\x07D\x07h\x07\x86\x07\x9E\x07\xB7\x07\xC7\x07\xD5\x07\xE5\x07\xFB\x08\ESC\x08C\x08p\x08\x8E\x08\xA6\x08\xB8\x08\xC2\x08\xCC\x08\xDA\x08\xE6\x08\xF4\x09\ACK\x09\x19\x09-\x09G\x09c\x09y\x09\x8B\x09\xA3\x09\xB9\x09\xC8\x09\xDA\x09\xE8\x09\xF8\LF\x10\LF(\LFB\LF^\LF\x81\LF\x9D\LF\xB3\LF\xCB\LF\xE5\LF\xFD\x0B\x13\x0B,\x0B>\x0BX\x0Br\x0B\x90\x0B\xAE\x0B\xCC\x0B\xED\x0C\x09\x0C%\x0CE\x0Ce\x0C}\x0C\x92\x0C\xA8\x0C\xBC\x0C\xD4\x0C\xEE\CR\x0C\CR,\CRO\CRk\CR\x87\CR\xA3\CR\xBD\CR\xD5\CR\xF0\x0E\ACK\x0E\x1C\x0E4\x0ER\x0En\x0E\x90\x0E\xB9\x0E\xDF\x0E\xFF\x0F\x1D\x0F?\x0F%\x0E\xB6\CR\xC3\x0C\x1F\LF:\x08e\ACK\xD3\ENQ\xA3\ENQ\x11\ENQE\ACK$\x07`\x08\x8F\x09}\LF\x12\LFV\LFb\LFH\LF\x16\x09\xDA\x09\x9D\x09k\x09C\x09\x16\x08\xF0\x08\xD8\x08\xC4\x08\xB4\x08\xAE\x08\xAE\x08\xB4\x08\xC0\x08\xC4\x08\xC2\x08\xB2\x08\xA4\x08\x94\x08x\x08Q\x08)\x07\xFB\x07\xD1\x07\xB3\x07\x98\x07\x82\x07h\x07N\x07B\x07B\x07D\x07@\x074\x07$\x07\x12\ACK\xF9\ACK\xDD\ACK\xBF\ACK\xA5\ACK\x93\ACK\x87\ACKy\ACKi\ACK[\ACKM\ACK:\ACK$\ACK\x08\ENQ\xE4\ENQ\xCC\ENQ\xB6\ENQ\xA0\ENQ\x83\ENQk\ENQY\ENQM\ENQM\ENQM\ENQK\ENQE\ENQA\ENQ?\ENQ5\ENQ%\ENQ\x11\ENQ\SOH\EOT\xF7\EOT\xEB\EOT\xE7\EOT\xE7\EOT\xED\EOT\xED\EOT\xEB\EOT\xE3\EOT\xD6\EOT\xCE\EOT\xCE\EOT\xC8\EOT\xBE\EOT\xB4\EOT\xAC\EOT\xA4\EOT\xAA\EOT\xA8\EOT\x9E\EOT\x94\EOT\x8C\EOT\x80\EOTn\EOTT\EOT8\EOT\x17\ETX\xFF\ETX\xE9\ETX\xD1\ETX\xC5\ETX\xB5\ETX\xA7\ETX\x8F\ETXx\ETX\\\ETX>\ETX$\ETX\x0E\STX\xE8\STX\xC5\STX\xA5\STX\x91\STX\x7F\STXm\STX]\STXG\STX-\STX\x1D\STX\x0C\SOH\xFA\SOH\xF0\SOH\xDE\SOH\xD0\SOH\xBE\SOH\xB2\SOH\xA4\SOH\x9A\SOH\x88\SOH~\SOHp\SOH]\SOHE\SOH3\SOH%\SOH\x17\SOH\ETX\NUL\xDF\NUL\xB0\NUL\x84\NULj\NULT\NUL>\NUL*\NUL\CAN\NUL\x0C\xFF\xFE\xFF\xF1\xFF\xE9\xFF\xE1\xFF\xE1\xFF\xE1\xFF\xE1\xFF\xE3\xFF\xEB\xFF\xEF\xFF\xF3\xFF\xF5\xFF\xF7\xFF\xF3\xFF\xF1\xFF\xEB\xFF\xE7\xFF\xE7\xFF\xE7\xFF\xE7\xFF\xE9\xFF\xEF\xFF\xF7\xFF\xF9\xFF\xFE\NUL\NUL\NUL\NUL\xFF\xFE\xFF\xF7\xFF\xF3\xFF\xED\xFF\xED\xFF\xED\xFF\xF3\xFF\xFC\NUL\EOT\NUL\x0C\NUL\x0E\NUL\x12\NUL\x12\NUL\x10\NUL\x08\NUL\STX\xFF\xFE\xFF\xF9\xFF\xF9\xFF\xF9\NUL\NUL\NUL\ACK\NUL\x0C\NUL\x12\NUL\x12\NUL\x10\NUL\LF\NUL\STX\xFF\xF9\xFF\xF3\xFF\xF3\xFF\xED\xFF\xED\xFF\xF1\xFF\xF7\xFF\xFE\NUL\EOT\NUL\ACK\NUL\ACK\NUL\EOT\xFF\xFA\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xF9\xFF\xFC\xFF\xF9\xFF\xF9\xFF\xF9\xFF\xFE\xFF\xF9\xFF\xF5\xFF\xEF\xFF\xE9\xFF\xE5\xFF\xE1\xFF\xE1\xFF\xE9\xFF\xED\xFF\xF5\xFF\xF9\xFF\xF9\NUL\NUL\xFF\xFE\xFF\xF9\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xEF\xFF\xF3\xFF\xF5\xFF\xFE\NUL\EOT\NUL\ACK\NUL\ACK\NUL\ACK\NUL\ACK\NUL\ACK\NUL\NUL\xFF\xF9\xFF\xF3
|
||||
127;125G100I00186'101S2015-06-01'102S15:53:56'103S'104S0'105S359194'106I00000'107I00000'110I00000'111I00000'112I00000'113I00000'114I00001'115I00000'116I00000'200I00003'201R00001.50'202I00000'203I36000'204I01979'205I08192'220I00002'221I09000'222I00000'223I09999'224I00771'225I00000'226I00001'227I00000'228I00001'229I00023'240I-9997'241I00001'242I00001'243I00001'244I00000'245I09998';\NUL\NUL\x08%\CR4\x111\NAK\xA6\CAN\ETX\x16\xD6\x14\CR\x0F\xBA\x0C\x12\x07\x85\EOT\xCB\ETX]\ETX\x80\EOT\x9E\ENQ\xE4\x07\x8B\x08\xCB\LFA\x0BM\x0Cq\CR:\x0E\x16\x0E\xAB\x0FM\x0F\xC1\x10>\x10\x93\x10\xF3\x115\x11}\x11\xAE\x11\xE3\x12\x08\x120\x12N\x12n\x12\x81\x12\x96\x12\xA4\x12\xB5\x12\xC1\x12\xCD\x12\xD4\x12\xD8\x12\xCA\x12\xA3\x12\x82\x12^\x12E\x12/\x12$\x12\x1A\x12\x13\x12\CR\x12\ACK\x11\xFF\x11\xF9\x11\xF0\x11\xE8\x11\xDE\x11\xDA\x11\xCF\x11\xC7\x11\xBC\x11\xB2\x11\xA8\x11\xA4\x11\x9E\x11\x9C\x11\x9C\x11\x9C\x11\x9D\x11\x9F\x11\x9F\x11\x9F\x11\xA0\x11\xA3\x11\xA7\x11\xA9\x11\xA9\x11\xAB\x11\xB2\x11\xBA\x11\xC3\x11\xCC\x11\xD7\x11\xE0\x11\xEB\x11\xF6\x12\ACK\x12\x11\x12"\x12/\x12@\x12M\x12b\x12r\x12\x86\x12\x9A\x12\xB3\x12\xC9\x12\xDD\x12\xF1\x13\x08\x13\x1C\x134\x13I\x13d\x13|\x13\x99\x13\xB3\x13\xD2\x13\xEC\x14\CR\x14%\x14F\x14_\x14\x7F\x14\x9A\x14\xBC\x14\xD9\x14\xFB\NAK\NAK\NAK7\NAKS\NAKw\NAK\x91\NAK\xB1\NAK\xC9\NAK\xE3\NAK\xF7\x16\x0F\x16"\x168\x16K\x16d\x16v\x16\x8D\x16\x9E\x16\xB2\x16\xC5\x16\xDE\x16\xF4\x17\x0E\x17"\x17>\x17T\x17u\x17\x91\x17\xB3\x17\xCF\x17\xEF\CAN\LF\CAN*\CAND\CANd\CAN\x7F\CAN\xA4\CAN\xC4\CAN\xEE\x19\x0F\x199\x19[\x19\x82\x19\xA3\x19\xC5\x19\xE1\x1A\ENQ\x1A#\x1AI\x1Al\x1A\x98\x1A\xBC\x1A\xE8\ESC\x0E\ESC>\ESCg\ESC\x9D\ESC\xCC\x1C\x08\x1C:\x1Cw\x1C\xAA\x1C\xE7\x1D\x17\x1DP\x1D~\x1D\xB8\x1D\xE8\x1E"\x1EO\x1E\x89\x1E\xBA\x1E\xF7\x1F(\x1Fj\x1F\xA1\x1F\xE2 \NAK Q \x82 \xBD \xEE!-!a!\xA5!\xDD"$"^"\xA7"\xDE###W#\x98#\xD0$\x1C$Y$\xA5$\xE4%4%v%\xC9&\x07&S&\x8F&\xD6'\x13'a'\x9F'\xEB(((y(\xBD)\x13)W)\xB0)\xF3*J*\x90*\xE4+-+\x81+\xAD+\xA5+}+\x1C*\xBF*:)\xD0)\\)!)\x11)\x1F)6)>)9)))\x0E(\xF7(\xD5(\xBE(\x9F(\x8B(t(c(P(?(,(\x1D(\x0B'\xFD'\xEC'\xDF'\xCE'\xC1'\xAE'\x9E'\x8B'|'j'Y'F'8'%'\x19'\LF&\xFF&\xEB&\xDC&\xCC&\xC1&\xB1&\xA5&\x94&\x88&w&j&Y&L&>&4&&&\x1C&\CR&\STX%\xF7%\xEE%\xDF%\xD1%\xC1%\xB7%\xAA%\x9E%\x89%{%j%]%O%C%6%+%\x1E%\x11%\NUL$\xF0$\xD8$\xC8$\xB2$\x9D$\x85$p$X$E$($\x0F#\xF1#\xDB#\xC0#\xA7#\x85#j#M#4#\x12"\xF6"\xD5"\xBA"\x9A"}"W":"\x12!\xF5!\xD0!\xB4!\x8F!r!Q!8!\x1A!\SOH \xE4 \xCC \xB3 \x9B } g L 6 \x1C \ENQ\x1F\xEA\x1F\xD3\x1F\xBA\x1F\xA5\x1F\x8B\x1Fv\x1F[\x1FF\x1F(\x1F\x13\x1E\xF4\x1E\xDB\x1E\xBF\x1E\xA9\x1E\x8F\x1Ew\x1E[\x1EB\x1E(\x1E\x12\x1D\xFB\x1D\xE5\x1D\xC4\x1D\xA5\x1Dz\x1DU\x1D(\x1D\x07\x1C\xDB\x1C\xBB\x1C\x95\x1Cx\x1CZ\x1CD\x1C*\x1C\x1C\x1C\LF\ESC\xFE\ESC\xF4\ESC\xEE\ESC\xEA\ESC\xE5\ESC\xE7\ESC\xE7\ESC\xE8\ESC\xEB\ESC\xF0\ESC\xF3\ESC\xF8\ESC\xFF\x1C\x08\x1C\x0B\x1C\x16\x1C\ESC\x1C#\x1C(\x1C/\x1C5\x1C<\x1C@\x1CH\x1CN\x1CT\x1CZ\x1Cb\x1Ce\x1Ck\x1Cp\x1Cv\x1Cy\x1C{\x1C{\x1Cx\x1Cv\x1Cr\x1Cq\x1Cp\x1Co\x1Co\x1Co\x1Co\x1Cp\x1Cq\x1Cq\x1Cq\x1Cq\x1Ct\x1Ct\x1Ct\x1Cv\x1Cs\x1Cu\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cw\x1Cx\x1Cz\x1Cz\x1C{\x1C{\x1C{\x1C{\x1C{\x1C}\x1C\x7F\x1C}\x1C~\x1C}\x1C}\x1C\x7F\x1C}\x1C}\x1C|\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{
|
||||
17
nettool/file/send.txt
Normal file
17
nettool/file/send.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
16 FF 01 01 E0 E1
|
||||
16 FF 01 01 E1 E2
|
||||
16 01 02 DF BC 16 01 02 DF BC 16 01 02 DF BC 12 13 14 15
|
||||
16 00 00 04 D0 F0 F1 65 C4
|
||||
16 00 00 04 D0 05 AB 5A C4
|
||||
16 01 10 02 F0 03 06 16 01 11 02 F0 03 06 16 01 12 02 F0 03 06 16 01 13 02 F0 03 06 16 01
|
||||
14 02 F0 03 06 16 01 15 02 F0 03 06 16 01 16 02 F0 03 06
|
||||
16 11 01 03 E8 01 10 0E
|
||||
16 11 01 03 E8 01 12 10
|
||||
16 11 01 03 E8 01 14 12
|
||||
16 11 01 03 E8 01 15 13
|
||||
DISARMEDALL
|
||||
BURGLARY 012
|
||||
BYPASS 012
|
||||
DISARMED 012
|
||||
16 00 01 01 D1 D3
|
||||
16 01 11 11
|
||||
17
nettool/form/form.pri
Normal file
17
nettool/form/form.pri
Normal file
@@ -0,0 +1,17 @@
|
||||
FORMS += \
|
||||
$$PWD/frmmain.ui \
|
||||
$$PWD/frmtcpclient.ui \
|
||||
$$PWD/frmtcpserver.ui \
|
||||
$$PWD/frmudpserver.ui
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/frmmain.h \
|
||||
$$PWD/frmtcpclient.h \
|
||||
$$PWD/frmtcpserver.h \
|
||||
$$PWD/frmudpserver.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/frmmain.cpp \
|
||||
$$PWD/frmtcpclient.cpp \
|
||||
$$PWD/frmtcpserver.cpp \
|
||||
$$PWD/frmudpserver.cpp
|
||||
20
nettool/form/frmmain.cpp
Normal file
20
nettool/form/frmmain.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "frmmain.h"
|
||||
#include "ui_frmmain.h"
|
||||
#include "quiwidget.h"
|
||||
|
||||
frmMain::frmMain(QWidget *parent) : QWidget(parent), ui(new Ui::frmMain)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->setCurrentIndex(App::CurrentIndex);
|
||||
}
|
||||
|
||||
frmMain::~frmMain()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmMain::on_tabWidget_currentChanged(int index)
|
||||
{
|
||||
App::CurrentIndex = index;
|
||||
App::writeConfig();
|
||||
}
|
||||
25
nettool/form/frmmain.h
Normal file
25
nettool/form/frmmain.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef FRMMAIN_H
|
||||
#define FRMMAIN_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class frmMain;
|
||||
}
|
||||
|
||||
class frmMain : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmMain(QWidget *parent = 0);
|
||||
~frmMain();
|
||||
|
||||
private slots:
|
||||
void on_tabWidget_currentChanged(int index);
|
||||
|
||||
private:
|
||||
Ui::frmMain *ui;
|
||||
};
|
||||
|
||||
#endif // FRMMAIN_H
|
||||
81
nettool/form/frmmain.ui
Normal file
81
nettool/form/frmmain.ui
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmMain</class>
|
||||
<widget class="QWidget" name="frmMain">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<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="QTabWidget" name="tabWidget">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="tabPosition">
|
||||
<enum>QTabWidget::South</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="frmTcpClient" name="tabTcpClient">
|
||||
<attribute name="title">
|
||||
<string>TCP客户端</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="frmTcpServer" name="tabTcpServer">
|
||||
<attribute name="title">
|
||||
<string>TCP服务器</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="frmUdpServer" name="tabUdpServer">
|
||||
<attribute name="title">
|
||||
<string>UDP服务器</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>frmTcpClient</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>frmtcpclient.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>frmTcpServer</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>frmtcpserver.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>frmUdpServer</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>frmudpserver.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
223
nettool/form/frmtcpclient.cpp
Normal file
223
nettool/form/frmtcpclient.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
#include "frmtcpclient.h"
|
||||
#include "ui_frmtcpclient.h"
|
||||
#include "quiwidget.h"
|
||||
|
||||
frmTcpClient::frmTcpClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmTcpClient)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
this->initConfig();
|
||||
}
|
||||
|
||||
frmTcpClient::~frmTcpClient()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmTcpClient::initForm()
|
||||
{
|
||||
isOk = false;
|
||||
tcpSocket = new QTcpSocket(this);
|
||||
connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected()));
|
||||
connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(disconnected()));
|
||||
connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(disconnected()));
|
||||
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
|
||||
timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
|
||||
|
||||
ui->cboxInterval->addItems(App::Intervals);
|
||||
ui->cboxData->addItems(App::Datas);
|
||||
}
|
||||
|
||||
void frmTcpClient::initConfig()
|
||||
{
|
||||
ui->ckHexSend->setChecked(App::HexSendTcpClient);
|
||||
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckHexReceive->setChecked(App::HexReceiveTcpClient);
|
||||
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAscii->setChecked(App::AsciiTcpClient);
|
||||
connect(ui->ckAscii, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckDebug->setChecked(App::DebugTcpClient);
|
||||
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoSend->setChecked(App::AutoSendTcpClient);
|
||||
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->cboxInterval->setCurrentIndex(ui->cboxInterval->findText(QString::number(App::IntervalTcpClient)));
|
||||
connect(ui->cboxInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->txtServerIP->setText(App::TcpServerIP);
|
||||
connect(ui->txtServerIP, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->txtServerPort->setText(QString::number(App::TcpServerPort));
|
||||
connect(ui->txtServerPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
|
||||
|
||||
timer->setInterval(App::IntervalTcpClient);
|
||||
App::AutoSendTcpClient ? timer->start() : timer->stop();
|
||||
}
|
||||
|
||||
void frmTcpClient::saveConfig()
|
||||
{
|
||||
App::HexSendTcpClient = ui->ckHexSend->isChecked();
|
||||
App::HexReceiveTcpClient = ui->ckHexReceive->isChecked();
|
||||
App::AsciiTcpClient = ui->ckAscii->isChecked();
|
||||
App::DebugTcpClient = ui->ckDebug->isChecked();
|
||||
App::AutoSendTcpClient = ui->ckAutoSend->isChecked();
|
||||
App::IntervalTcpClient = ui->cboxInterval->currentText().toInt();
|
||||
App::TcpServerIP = ui->txtServerIP->text().trimmed();
|
||||
App::TcpServerPort = ui->txtServerPort->text().trimmed().toInt();
|
||||
App::writeConfig();
|
||||
|
||||
timer->setInterval(App::IntervalTcpClient);
|
||||
App::AutoSendTcpClient ? timer->start() : timer->stop();
|
||||
}
|
||||
|
||||
void frmTcpClient::append(int type, const QString &data, bool clear)
|
||||
{
|
||||
static int currentCount = 0;
|
||||
static int maxCount = 100;
|
||||
|
||||
if (clear) {
|
||||
ui->txtMain->clear();
|
||||
currentCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentCount >= maxCount) {
|
||||
ui->txtMain->clear();
|
||||
currentCount = 0;
|
||||
}
|
||||
|
||||
if (ui->ckShow->isChecked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//过滤回车换行符
|
||||
QString strData = data;
|
||||
strData = strData.replace("\r", "");
|
||||
strData = strData.replace("\n", "");
|
||||
|
||||
//不同类型不同颜色显示
|
||||
QString strType;
|
||||
if (type == 0) {
|
||||
strType = "发送";
|
||||
ui->txtMain->setTextColor(QColor("darkgreen"));
|
||||
} else {
|
||||
strType = "接收";
|
||||
ui->txtMain->setTextColor(QColor("red"));
|
||||
}
|
||||
|
||||
strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData);
|
||||
ui->txtMain->append(strData);
|
||||
currentCount++;
|
||||
}
|
||||
|
||||
void frmTcpClient::connected()
|
||||
{
|
||||
isOk = true;
|
||||
ui->btnConnect->setText("断开");
|
||||
append(0, "服务器连接");
|
||||
}
|
||||
|
||||
void frmTcpClient::disconnected()
|
||||
{
|
||||
isOk = false;
|
||||
tcpSocket->abort();
|
||||
ui->btnConnect->setText("连接");
|
||||
append(1, "服务器断开");
|
||||
}
|
||||
|
||||
void frmTcpClient::readData()
|
||||
{
|
||||
QByteArray data = tcpSocket->readAll();
|
||||
if (data.length() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString buffer;
|
||||
if (App::HexReceiveTcpClient) {
|
||||
buffer = QUIHelper::byteArrayToHexStr(data);
|
||||
} else if (App::AsciiTcpClient) {
|
||||
buffer = QUIHelper::byteArrayToAsciiStr(data);
|
||||
} else {
|
||||
buffer = QString(data);
|
||||
}
|
||||
|
||||
append(1, buffer);
|
||||
|
||||
//自动回复数据,可以回复的数据是以;隔开,每行可以带多个;所以这里不需要继续判断
|
||||
if (App::DebugTcpClient) {
|
||||
int count = App::Keys.count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (App::Keys.at(i) == buffer) {
|
||||
sendData(App::Values.at(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmTcpClient::sendData(const QString &data)
|
||||
{
|
||||
QByteArray buffer;
|
||||
if (App::HexSendTcpClient) {
|
||||
buffer = QUIHelper::hexStrToByteArray(data);
|
||||
} else if (App::AsciiTcpClient) {
|
||||
buffer = QUIHelper::asciiStrToByteArray(data);
|
||||
} else {
|
||||
buffer = data.toLatin1();
|
||||
}
|
||||
|
||||
tcpSocket->write(buffer);
|
||||
append(0, data);
|
||||
}
|
||||
|
||||
void frmTcpClient::on_btnConnect_clicked()
|
||||
{
|
||||
if (ui->btnConnect->text() == "连接") {
|
||||
tcpSocket->abort();
|
||||
tcpSocket->connectToHost(App::TcpServerIP, App::TcpServerPort);
|
||||
} else {
|
||||
tcpSocket->abort();
|
||||
}
|
||||
}
|
||||
|
||||
void frmTcpClient::on_btnSave_clicked()
|
||||
{
|
||||
QString data = ui->txtMain->toPlainText();
|
||||
if (data.length() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString fileName = QString("%1/%2.txt").arg(QUIHelper::appPath()).arg(STRDATETIME);
|
||||
QFile file(fileName);
|
||||
if (file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
file.write(data.toUtf8());
|
||||
file.close();
|
||||
}
|
||||
|
||||
on_btnClear_clicked();
|
||||
}
|
||||
|
||||
void frmTcpClient::on_btnClear_clicked()
|
||||
{
|
||||
append(0, "", true);
|
||||
}
|
||||
|
||||
void frmTcpClient::on_btnSend_clicked()
|
||||
{
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString data = ui->cboxData->currentText();
|
||||
if (data.length() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendData(data);
|
||||
}
|
||||
44
nettool/form/frmtcpclient.h
Normal file
44
nettool/form/frmtcpclient.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef FRMTCPCLIENT_H
|
||||
#define FRMTCPCLIENT_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QtNetwork>
|
||||
|
||||
namespace Ui {
|
||||
class frmTcpClient;
|
||||
}
|
||||
|
||||
class frmTcpClient : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmTcpClient(QWidget *parent = 0);
|
||||
~frmTcpClient();
|
||||
|
||||
private:
|
||||
Ui::frmTcpClient *ui;
|
||||
|
||||
bool isOk;
|
||||
QTcpSocket *tcpSocket;
|
||||
QTimer *timer;
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
void initConfig();
|
||||
void saveConfig();
|
||||
void append(int type, const QString &data, bool clear = false);
|
||||
|
||||
void connected();
|
||||
void disconnected();
|
||||
void readData();
|
||||
void sendData(const QString &data);
|
||||
|
||||
private slots:
|
||||
void on_btnConnect_clicked();
|
||||
void on_btnSave_clicked();
|
||||
void on_btnClear_clicked();
|
||||
void on_btnSend_clicked();
|
||||
};
|
||||
|
||||
#endif // FRMTCPCLIENT_H
|
||||
213
nettool/form/frmtcpclient.ui
Normal file
213
nettool/form/frmtcpclient.ui
Normal file
@@ -0,0 +1,213 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>frmTcpClient</class>
|
||||
<widget class="QWidget" name="frmTcpClient">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="txtMain">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>170</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>170</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ckHexReceive">
|
||||
<property name="text">
|
||||
<string>16进制接收</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ckHexSend">
|
||||
<property name="text">
|
||||
<string>16进制发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ckAscii">
|
||||
<property name="text">
|
||||
<string>Ascii控制字符</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ckShow">
|
||||
<property name="text">
|
||||
<string>暂停显示</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ckDebug">
|
||||
<property name="text">
|
||||
<string>模拟设备</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ckAutoSend">
|
||||
<property name="text">
|
||||
<string>定时发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboxInterval"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labServerIP">
|
||||
<property name="text">
|
||||
<string>服务器IP地址</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="txtServerIP"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labServerPort">
|
||||
<property name="text">
|
||||
<string>服务器端口</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="txtServerPort"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnConnect">
|
||||
<property name="text">
|
||||
<string>连接</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSave">
|
||||
<property name="text">
|
||||
<string>保存</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnClear">
|
||||
<property name="text">
|
||||
<string>清空</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QHBoxLayout" name="layTcpClient">
|
||||
<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="QComboBox" name="cboxData">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnSend">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>发送</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
232
nettool/form/frmtcpserver.cpp
Normal file
232
nettool/form/frmtcpserver.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
#include "frmtcpserver.h"
|
||||
#include "ui_frmtcpserver.h"
|
||||
#include "quiwidget.h"
|
||||
|
||||
frmTcpServer::frmTcpServer(QWidget *parent) : QWidget(parent), ui(new Ui::frmTcpServer)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
this->initForm();
|
||||
this->initConfig();
|
||||
}
|
||||
|
||||
frmTcpServer::~frmTcpServer()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void frmTcpServer::initForm()
|
||||
{
|
||||
isOk = false;
|
||||
tcpServer = new TcpServer(this);
|
||||
connect(tcpServer, SIGNAL(clientConnected(QString, int)), this, SLOT(clientConnected(QString, int)));
|
||||
connect(tcpServer, SIGNAL(clientDisconnected(QString, int)), this, SLOT(clientDisconnected(QString, int)));
|
||||
connect(tcpServer, SIGNAL(sendData(QString, int, QString)), this, SLOT(sendData(QString, int, QString)));
|
||||
connect(tcpServer, SIGNAL(receiveData(QString, int, QString)), this, SLOT(receiveData(QString, int, QString)));
|
||||
|
||||
timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
|
||||
|
||||
ui->cboxInterval->addItems(App::Intervals);
|
||||
ui->cboxData->addItems(App::Datas);
|
||||
QUIHelper::setLabStyle(ui->labCount, 3);
|
||||
}
|
||||
|
||||
void frmTcpServer::initConfig()
|
||||
{
|
||||
ui->ckHexSend->setChecked(App::HexSendTcpServer);
|
||||
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckHexReceive->setChecked(App::HexReceiveTcpServer);
|
||||
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAscii->setChecked(App::AsciiTcpServer);
|
||||
connect(ui->ckAscii, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckDebug->setChecked(App::DebugTcpServer);
|
||||
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckAutoSend->setChecked(App::AutoSendTcpServer);
|
||||
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->ckSelectAll->setChecked(App::SelectAllTcpServer);
|
||||
connect(ui->ckSelectAll, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->cboxInterval->setCurrentIndex(ui->cboxInterval->findText(QString::number(App::IntervalTcpServer)));
|
||||
connect(ui->cboxInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
|
||||
|
||||
ui->txtListenPort->setText(QString::number(App::TcpListenPort));
|
||||
connect(ui->txtListenPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
|
||||
|
||||
timer->setInterval(App::IntervalTcpServer);
|
||||
App::AutoSendTcpServer ? timer->start() : timer->stop();
|
||||
}
|
||||
|
||||
void frmTcpServer::saveConfig()
|
||||
{
|
||||
App::HexSendTcpServer = ui->ckHexSend->isChecked();
|
||||
App::HexReceiveTcpServer = ui->ckHexReceive->isChecked();
|
||||
App::AsciiTcpServer = ui->ckAscii->isChecked();
|
||||
App::DebugTcpServer = ui->ckDebug->isChecked();
|
||||
App::AutoSendTcpServer = ui->ckAutoSend->isChecked();
|
||||
App::SelectAllTcpServer = ui->ckSelectAll->isChecked();
|
||||
App::IntervalTcpServer = ui->cboxInterval->currentText().toInt();
|
||||
App::TcpListenPort = ui->txtListenPort->text().trimmed().toInt();
|
||||
App::writeConfig();
|
||||
|
||||
timer->setInterval(App::IntervalTcpServer);
|
||||
App::AutoSendTcpServer ? timer->start() : timer->stop();
|
||||
}
|
||||
|
||||
void frmTcpServer::append(int type, const QString &data, bool clear)
|
||||
{
|
||||
static int currentCount = 0;
|
||||
static int maxCount = 100;
|
||||
|
||||
if (clear) {
|
||||
ui->txtMain->clear();
|
||||
currentCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentCount >= maxCount) {
|
||||
ui->txtMain->clear();
|
||||
currentCount = 0;
|
||||
}
|
||||
|
||||
if (ui->ckShow->isChecked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//过滤回车换行符
|
||||
QString strData = data;
|
||||
strData = strData.replace("\r", "");
|
||||
strData = strData.replace("\n", "");
|
||||
|
||||
//不同类型不同颜色显示
|
||||
QString strType;
|
||||
if (type == 0) {
|
||||
strType = "发送";
|
||||
ui->txtMain->setTextColor(QColor("darkgreen"));
|
||||
} else {
|
||||
strType = "接收";
|
||||
ui->txtMain->setTextColor(QColor("red"));
|
||||
}
|
||||
|
||||
strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData);
|
||||
ui->txtMain->append(strData);
|
||||
currentCount++;
|
||||
}
|
||||
|
||||
void frmTcpServer::sendData(const QString &data)
|
||||
{
|
||||
if (ui->ckSelectAll->isChecked()) {
|
||||
tcpServer->writeData(data);
|
||||
} else {
|
||||
int row = ui->listWidget->currentRow();
|
||||
if (row >= 0) {
|
||||
QString str = ui->listWidget->item(row)->text();
|
||||
QStringList list = str.split(":");
|
||||
tcpServer->writeData(list.at(0), list.at(1).toInt(), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void frmTcpServer::clientConnected(const QString &ip, int port)
|
||||
{
|
||||
QString str = QString("%1:%2").arg(ip).arg(port);
|
||||
ui->listWidget->addItem(str);
|
||||
ui->labCount->setText(QString("共 %1 个连接").arg(ui->listWidget->count()));
|
||||
}
|
||||
|
||||
void frmTcpServer::clientDisconnected(const QString &ip, int port)
|
||||
{
|
||||
int row = -1;
|
||||
QString str = QString("%1:%2").arg(ip).arg(port);
|
||||
for (int i = 0; i < ui->listWidget->count(); i++) {
|
||||
if (ui->listWidget->item(i)->text() == str) {
|
||||
row = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete ui->listWidget->takeItem(row);
|
||||
ui->labCount->setText(QString("共 %1 个连接").arg(ui->listWidget->count()));
|
||||
}
|
||||
|
||||
void frmTcpServer::sendData(const QString &ip, int port, const QString &data)
|
||||
{
|
||||
QString str = QString("[%1:%2] %3").arg(ip).arg(port).arg(data);
|
||||
bool error = (data.contains("下线") || data.contains("离线"));
|
||||
append(error ? 1 : 0, str);
|
||||
}
|
||||
|
||||
void frmTcpServer::receiveData(const QString &ip, int port, const QString &data)
|
||||
{
|
||||
QString str = QString("[%1:%2] %3").arg(ip).arg(port).arg(data);
|
||||
append(1, str);
|
||||
}
|
||||
|
||||
void frmTcpServer::on_btnListen_clicked()
|
||||
{
|
||||
if (ui->btnListen->text() == "监听") {
|
||||
isOk = tcpServer->start();
|
||||
if (isOk) {
|
||||
append(0, "监听成功");
|
||||
ui->btnListen->setText("关闭");
|
||||
}
|
||||
} else {
|
||||
isOk = false;
|
||||
tcpServer->stop();
|
||||
ui->btnListen->setText("监听");
|
||||
}
|
||||
}
|
||||
|
||||
void frmTcpServer::on_btnSave_clicked()
|
||||
{
|
||||
QString data = ui->txtMain->toPlainText();
|
||||
if (data.length() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString fileName = QString("%1/%2.txt").arg(QUIHelper::appPath()).arg(STRDATETIME);
|
||||
QFile file(fileName);
|
||||
if (file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
file.write(data.toUtf8());
|
||||
file.close();
|
||||
}
|
||||
|
||||
on_btnClear_clicked();
|
||||
}
|
||||
|
||||
void frmTcpServer::on_btnClear_clicked()
|
||||
{
|
||||
append(0, "", true);
|
||||
}
|
||||
|
||||
void frmTcpServer::on_btnSend_clicked()
|
||||
{
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString data = ui->cboxData->currentText();
|
||||
if (data.length() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendData(data);
|
||||
}
|
||||
|
||||
void frmTcpServer::on_btnClose_clicked()
|
||||
{
|
||||
if (ui->ckSelectAll->isChecked()) {
|
||||
tcpServer->remove();
|
||||
} else {
|
||||
int row = ui->listWidget->currentRow();
|
||||
if (row >= 0) {
|
||||
QString str = ui->listWidget->item(row)->text();
|
||||
QStringList list = str.split(":");
|
||||
tcpServer->remove(list.at(0), list.at(1).toInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
48
nettool/form/frmtcpserver.h
Normal file
48
nettool/form/frmtcpserver.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef FRMTCPSERVER_H
|
||||
#define FRMTCPSERVER_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "tcpserver.h"
|
||||
|
||||
namespace Ui {
|
||||
class frmTcpServer;
|
||||
}
|
||||
|
||||
class frmTcpServer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit frmTcpServer(QWidget *parent = 0);
|
||||
~frmTcpServer();
|
||||
|
||||
private:
|
||||
Ui::frmTcpServer *ui;
|
||||
|
||||
bool isOk;
|
||||
TcpServer *tcpServer;
|
||||
QTimer *timer;
|
||||
|
||||
private slots:
|
||||
void initForm();
|
||||
void initConfig();
|
||||
void saveConfig();
|
||||
void append(int type, const QString &data, bool clear = false);
|
||||
|
||||
private slots:
|
||||
void sendData(const QString &data);
|
||||
|
||||
void clientConnected(const QString &ip, int port);
|
||||
void clientDisconnected(const QString &ip, int port);
|
||||
void sendData(const QString &ip, int port, const QString &data);
|
||||
void receiveData(const QString &ip, int port, const QString &data);
|
||||
|
||||
private slots:
|
||||
void on_btnListen_clicked();
|
||||
void on_btnSave_clicked();
|
||||
void on_btnClear_clicked();
|
||||
void on_btnSend_clicked();
|
||||
void on_btnClose_clicked();
|
||||
};
|
||||
|
||||
#endif // FRMTCPSERVER_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user