改进大量代码

This commit is contained in:
feiyangqingyun
2021-05-15 19:09:26 +08:00
parent c574db4f26
commit 8fcebd5b73
58 changed files with 4772 additions and 14431 deletions

View File

@@ -1,7 +1,5 @@
HEADERS += \
$$PWD/appconfig.h \
$$PWD/quiwidget.h
$$PWD/appconfig.h
SOURCES += \
$$PWD/appconfig.cpp \
$$PWD/quiwidget.cpp
$$PWD/appconfig.cpp

View File

@@ -1,160 +0,0 @@
#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 = QString::fromUtf8("");
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 (!QUIHelper::checkIniFile(App::ConfigFile)) {
writeConfig();
return;
}
QSettings set(App::ConfigFile, QSettings::IniFormat);
set.beginGroup("ComConfig");
App::PortName = set.value("PortName", App::PortName).toString();
App::BaudRate = set.value("BaudRate", App::BaudRate).toInt();
App::DataBit = set.value("DataBit", App::DataBit).toInt();
App::Parity = set.value("Parity", App::Parity).toString();
App::StopBit = set.value("StopBit", App::StopBit).toInt();
App::HexSend = set.value("HexSend", App::HexSend).toBool();
App::HexReceive = set.value("HexReceive", App::HexReceive).toBool();
App::Debug = set.value("Debug", App::Debug).toBool();
App::AutoClear = set.value("AutoClear", App::AutoClear).toBool();
App::AutoSend = set.value("AutoSend", App::AutoSend).toBool();
App::SendInterval = set.value("SendInterval", App::SendInterval).toInt();
App::AutoSave = set.value("AutoSave", App::AutoSave).toBool();
App::SaveInterval = set.value("SaveInterval", App::SaveInterval).toInt();
set.endGroup();
set.beginGroup("NetConfig");
App::Mode = set.value("Mode", App::Mode).toString();
App::ServerIP = set.value("ServerIP", App::ServerIP).toString();
App::ServerPort = set.value("ServerPort", App::ServerPort).toInt();
App::ListenPort = set.value("ListenPort", App::ListenPort).toInt();
App::SleepTime = set.value("SleepTime", App::SleepTime).toInt();
App::AutoConnect = set.value("AutoConnect", App::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();
}
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();
}
if (App::Datas.count() == 0) {
App::Datas << "16 FF 01 01 E0 E1" << "16 FF 01 01 E1 E2";
}
}
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();
}
}

View File

@@ -1,48 +0,0 @@
#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 QStringList Intervals;
static QStringList Datas;
static QStringList Keys;
static QStringList Values;
static void readSendData();
static void readDeviceData();
};
#endif // APP_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,875 +0,0 @@
#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
#define DialogMinWidth 350
#define DialogMinHeight 180
#else
#define TitleMinSize 30
#define DialogMinWidth 280
#define DialogMinHeight 150
#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 showEvent(QShowEvent *);
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 *labCountDown;
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 setIconMsg(const QString &png, const QChar &str);
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 showEvent(QShowEvent *);
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 *labCountDown;
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 *labCountDown;
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:
void showEvent(QShowEvent *);
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();
//获取uuid
static QString getUuid();
//初始化数据库
static void initDb(const QString &dbName);
//初始化文件,不存在则拷贝
static void initFile(const QString &sourceName, const QString &targetName);
//检查ini配置文件
static bool checkIniFile(const QString &iniFile);
//设置图标到按钮
static void setIconBtn(QAbstractButton *btn, const QString &png, const QChar &str);
//新建目录
static void newDir(const QString &dirName);
//写入消息到额外的的消息日志文件
static void writeInfo(const QString &info, bool needWrite = false, const QString &filePath = "log");
static void writeError(const QString &info, bool needWrite = false, const QString &filePath = "log");
//设置无边框窗体
static void setFramelessForm(QWidget *widgetMain, QWidget *widgetTitle, QLabel *labIco, QPushButton *btnClose, bool tool = true);
//设置全局样式
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, const QString &bgColor = "", const QString &textColor = "");
//设置窗体居中显示
static void setFormInCenter(QWidget *frm);
//设置翻译文件
static void setTranslator(const QString &qmFile = ":/image/qt_zh_CN.qm");
//设置编码
static void setCode();
//设置字体
static void setFont(const QString &ttfFile = ":/image/DroidSansFallback.ttf",
const QString &fontName = "Microsoft Yahei", int fontSize = 12);
//设置延时
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 QString getIP(const QString &url);
//判断是否是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);
//IP地址字符串与整型转换
static QString ipv4IntToString(quint32 ip);
static quint32 ipv4StringToInt(const QString &ip);
//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);
//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 void initAsciiStr();
static QString byteArrayToAsciiStr(const QByteArray &data);
static QByteArray asciiStrToByteArray(const QString &data);
//16进制字符串与字节数组互转
static char hexStrToChar(char data);
static QByteArray hexStrToByteArray(const QString &data);
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 QString saveFileName(const QString &filter, const QString &defaultDir = "", const QString &fileName = "");
//获取选择的文件集合
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 &html);
//获取本机IP
static QString getLocalIP();
//获取本机IP地址集合
static QStringList getLocalIPs();
//Url地址转为IP地址
static QString urlToIP(const QString &url);
//字符串补全
static QString getValue(quint8 value);
//判断是否通外网
static bool isWebOk();
//初始化表格
static void initTableView(QTableView *tableView, int rowHeight = 25,
bool headVisible = false, bool edit = false,
bool stretchLast = true);
//弹出框
static int showMessageBox(const QString &info, int type = 0, int closeSec = 0, bool exec = false);
//弹出消息框
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

View File

@@ -21,17 +21,20 @@ CONFIG += warn_off
INCLUDEPATH += $$PWD
INCLUDEPATH += $$PWD/api
INCLUDEPATH += $$PWD/form
INCLUDEPATH += $$PWD/qextserialport
include ($$PWD/api/api.pri)
include ($$PWD/form/form.pri)
include ($$PWD/qextserialport/qextserialport.pri)
unix {
INCLUDEPATH += $$PWD/../core_qui
include ($$PWD/../core_qui/core_qui.pri)
INCLUDEPATH += $$PWD/../3rd_qextserialport
include ($$PWD/../3rd_qextserialport/3rd_qextserialport.pri)
unix:!macx {
contains(arma7, DEFINES) {
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
}
}
}}

File diff suppressed because it is too large Load Diff

View File

@@ -1,234 +0,0 @@
/****************************************************************************
** 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

View File

@@ -1,9 +0,0 @@
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

View File

@@ -1,72 +0,0 @@
/****************************************************************************
** 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

View File

@@ -1,277 +0,0 @@
/****************************************************************************
** 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_

View File

@@ -1,559 +0,0 @@
/****************************************************************************
** 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(&currentTermios); // 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(&currentTermios, B50);
break;
case BAUD75:
setBaudRate2Termios(&currentTermios, B75);
break;
case BAUD110:
setBaudRate2Termios(&currentTermios, B110);
break;
case BAUD134:
setBaudRate2Termios(&currentTermios, B134);
break;
case BAUD150:
setBaudRate2Termios(&currentTermios, B150);
break;
case BAUD200:
setBaudRate2Termios(&currentTermios, B200);
break;
case BAUD300:
setBaudRate2Termios(&currentTermios, B300);
break;
case BAUD600:
setBaudRate2Termios(&currentTermios, B600);
break;
case BAUD1200:
setBaudRate2Termios(&currentTermios, B1200);
break;
case BAUD1800:
setBaudRate2Termios(&currentTermios, B1800);
break;
case BAUD2400:
setBaudRate2Termios(&currentTermios, B2400);
break;
case BAUD4800:
setBaudRate2Termios(&currentTermios, B4800);
break;
case BAUD9600:
setBaudRate2Termios(&currentTermios, B9600);
break;
case BAUD19200:
setBaudRate2Termios(&currentTermios, B19200);
break;
case BAUD38400:
setBaudRate2Termios(&currentTermios, B38400);
break;
case BAUD57600:
setBaudRate2Termios(&currentTermios, B57600);
break;
#ifdef B76800
case BAUD76800:
setBaudRate2Termios(&currentTermios, B76800);
break;
#endif
case BAUD115200:
setBaudRate2Termios(&currentTermios, B115200);
break;
#if defined(B230400) && defined(B4000000)
case BAUD230400:
setBaudRate2Termios(&currentTermios, B230400);
break;
case BAUD460800:
setBaudRate2Termios(&currentTermios, B460800);
break;
case BAUD500000:
setBaudRate2Termios(&currentTermios, B500000);
break;
case BAUD576000:
setBaudRate2Termios(&currentTermios, B576000);
break;
case BAUD921600:
setBaudRate2Termios(&currentTermios, B921600);
break;
case BAUD1000000:
setBaudRate2Termios(&currentTermios, B1000000);
break;
case BAUD1152000:
setBaudRate2Termios(&currentTermios, B1152000);
break;
case BAUD1500000:
setBaudRate2Termios(&currentTermios, B1500000);
break;
case BAUD2000000:
setBaudRate2Termios(&currentTermios, B2000000);
break;
case BAUD2500000:
setBaudRate2Termios(&currentTermios, B2500000);
break;
case BAUD3000000:
setBaudRate2Termios(&currentTermios, B3000000);
break;
case BAUD3500000:
setBaudRate2Termios(&currentTermios, B3500000);
break;
case BAUD4000000:
setBaudRate2Termios(&currentTermios, B4000000);
break;
#endif
#ifdef Q_OS_MAC
default:
setBaudRate2Termios(&currentTermios, 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, &currentTermios);
}
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, &currentTermios);
currentTermios.c_cc[VTIME] = millisec / 100;
::tcsetattr(fd, TCSAFLUSH, &currentTermios);
}
settingsDirtyFlags = 0;
}

View File

@@ -1,476 +0,0 @@
/****************************************************************************
** 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;
}

View File

@@ -1,16 +0,0 @@
ʹ<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);
}