彻底改版2.0

This commit is contained in:
feiyangqingyun
2021-11-17 16:41:30 +08:00
parent a7f4347959
commit ebfd531a91
2622 changed files with 8915 additions and 7263 deletions

BIN
other/0snap/bgdemo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
other/0snap/dbpage.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

BIN
other/0snap/echartgauge.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
other/0snap/mouseline.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
other/0snap/ntpclient.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
other/0snap/trayicon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

14
other/bgdemo/bgdemo.pro Normal file
View File

@@ -0,0 +1,14 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
TARGET = bgdemo
TEMPLATE = app
DESTDIR = $$PWD/../bin
CONFIG += warn_off
SOURCES += main.cpp
SOURCES += widget.cpp
HEADERS += widget.h
FORMS += widget.ui
RESOURCES += rc.qrc

BIN
other/bgdemo/image/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

BIN
other/bgdemo/image/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

BIN
other/bgdemo/image/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
other/bgdemo/image/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
other/bgdemo/image/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

11
other/bgdemo/main.cpp Normal file
View File

@@ -0,0 +1,11 @@
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

9
other/bgdemo/rc.qrc Normal file
View File

@@ -0,0 +1,9 @@
<RCC>
<qresource prefix="/">
<file>image/1.png</file>
<file>image/2.png</file>
<file>image/3.png</file>
<file>image/4.png</file>
<file>image/5.png</file>
</qresource>
</RCC>

56
other/bgdemo/widget.cpp Normal file
View File

@@ -0,0 +1,56 @@
#include "widget.h"
#include "ui_widget.h"
#include "qevent.h"
#include "qdebug.h"
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
this->setAttribute(Qt::WA_TranslucentBackground);
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint);
ui->widget->installEventFilter(this);
ui->widget->setStyleSheet(QString("background-image:url(:/image/%1.png);").arg(1));
}
Widget::~Widget()
{
delete ui;
}
bool Widget::eventFilter(QObject *watched, QEvent *evt)
{
static int index = 1;
static QPoint mousePoint;
static bool mousePressed = false;
QMouseEvent *event = static_cast<QMouseEvent *>(evt);
if (event->type() == QEvent::MouseButtonPress) {
if (event->button() == Qt::LeftButton) {
mousePressed = true;
mousePoint = event->globalPos() - this->pos();
if (index == 5) {
index = 1;
} else {
index++;
}
ui->widget->setStyleSheet(QString("background-image:url(:/image/%1.png);").arg(index));
return true;
} else {
exit(0);
}
} else if (event->type() == QEvent::MouseButtonRelease) {
mousePressed = false;
return true;
} else if (event->type() == QEvent::MouseMove) {
if (mousePressed && (event->buttons() && Qt::LeftButton)) {
this->move(event->globalPos() - mousePoint);
return true;
}
}
return QWidget::eventFilter(watched, event);
}

25
other/bgdemo/widget.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
bool eventFilter(QObject *watched, QEvent *evt);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H

44
other/bgdemo/widget.ui Normal file
View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>712</width>
<height>353</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<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="QWidget" name="widget" native="true">
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

BIN
other/dbpage/TA.db Normal file

Binary file not shown.

557
other/dbpage/dbpage.cpp Normal file
View File

@@ -0,0 +1,557 @@
#pragma execution_character_set("utf-8")
#include "dbpage.h"
SqlQueryModel::SqlQueryModel(QObject *parent) : QSqlQueryModel(parent)
{
allCenter = false;
alignCenterColumn.clear();
alignRightColumn.clear();
}
QVariant SqlQueryModel::data(const QModelIndex &index, int role) const
{
QVariant value = QSqlQueryModel::data(index, role);
if (allCenter) {
if (role == Qt::TextAlignmentRole) {
value = Qt::AlignCenter;
}
} else {
//逐个从列索引中查找是否当前列在其中
int column = index.column();
bool existCenter = alignCenterColumn.contains(column);
bool existRight = alignRightColumn.contains(column);
if (role == Qt::TextAlignmentRole) {
if (existCenter) {
value = Qt::AlignCenter;
}
if (existRight) {
value = (QVariant)(Qt::AlignVCenter | Qt::AlignRight);
}
}
}
//实现鼠标经过整行换色,如果设置了hoverRow才需要处理
if (property("hoverRow").isValid()) {
int row = property("hoverRow").toInt();
if (row == index.row()) {
if (role == Qt::BackgroundRole) {
value = QColor(property("hoverBgColor").toString());
} else if (role == Qt::ForegroundRole) {
value = QColor(property("hoverTextColor").toString());
}
}
}
//实现隐藏部分显示,指定列和替换字符
if (property("hideColumn").isValid()) {
int column = property("hideColumn").toInt();
if (column == index.column()) {
if (role == Qt::DisplayRole) {
QString letter = property("hideLetter").toString();
int start = property("hideStart").toInt();
int end = property("hideEnd").toInt();
QString str = value.toString();
QStringList list;
for (int i = 0; i < str.length(); i++) {
if (i >= start && i <= end) {
list << letter;
} else {
list << str.at(i);
}
}
value = list.join("");
}
}
}
return value;
}
void SqlQueryModel::setAllCenter(bool allCenter)
{
this->allCenter = allCenter;
}
void SqlQueryModel::setAlignCenterColumn(const QList<int> &alignCenterColumn)
{
this->alignCenterColumn = alignCenterColumn;
}
void SqlQueryModel::setAlignRightColumn(const QList<int> &alignRightColumn)
{
this->alignRightColumn = alignRightColumn;
}
DbCountThread::DbCountThread(QObject *parent) : QThread(parent)
{
connName = "qt_sql_default_connection";
sql = "select 1";
connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));
}
void DbCountThread::run()
{
select();
}
void DbCountThread::setConnName(const QString &connName)
{
this->connName = connName;
}
void DbCountThread::setSql(const QString &sql)
{
this->sql = sql;
}
void DbCountThread::select()
{
//计算用时
QDateTime dtStart = QDateTime::currentDateTime();
int count = 0;
QSqlQuery query(QSqlDatabase::database(connName));
if (query.exec(sql)) {
if (query.next()) {
count = query.value(0).toUInt();
}
}
QDateTime dtEnd = QDateTime::currentDateTime();
double msec = dtStart.msecsTo(dtEnd);
emit receiveCount(count, msec);
}
DbPage::DbPage(QObject *parent) : QObject(parent)
{
startIndex = 0;
queryModel = new SqlQueryModel;
pageCurrent = 1;
pageTotal = 0;
recordsTotal = 0;
recordsPerpage = 0;
labPageTotal = 0;
labPageCurrent = 0;
labRecordsTotal = 0;
labRecordsPerpage = 0;
labSelectTime = 0;
labSelectInfo = 0;
tableView = 0;
btnFirst = 0;
btnPrevious = 0;
btnNext = 0;
btnLast = 0;
countName = "*";
connName = "qt_sql_default_connection";
dbType = DbType_Sqlite;
pageCurrent = 0;
pageTotal = 0;
recordsTotal = 0;
recordsPerpage = 30;
tableName = "";
selectColumn = "*";
orderSql = "";
whereSql = "";
columnNames.clear();
columnWidths.clear();
insertColumnIndex = -1;
insertColumnName = "";
insertColumnWidth = 50;
}
void DbPage::bindData(const QString &columnName, const QString &orderColumn, const QString &tableName,
QComboBox *cbox, const QString &connName)
{
QSqlQuery query(QSqlDatabase::database(connName));
query.exec("select " + columnName + " from " + tableName + " order by " + orderColumn + " asc");
while (query.next()) {
cbox->addItem(query.value(0).toString());
}
}
void DbPage::bindData(const QString &columnName, const QString &orderColumn, const QString &tableName,
QList<QComboBox *> cboxs, const QString &connName)
{
QSqlQuery query(QSqlDatabase::database(connName));
query.exec("select " + columnName + " from " + tableName + " order by " + orderColumn + " asc");
while (query.next()) {
foreach (QComboBox *cbox, cboxs) {
cbox->addItem(query.value(0).toString());
}
}
}
void DbPage::bindData(const QString &sql)
{
queryModel->setQuery(sql, QSqlDatabase::database(connName));
tableView->setModel(queryModel);
//依次设置列标题列宽
int columnCount = tableView->model()->columnCount();
int nameCount = columnNames.count();
columnCount = columnCount > nameCount ? nameCount : columnCount;
QList<QString> columnNames = this->columnNames;
QList<int> columnWidths = this->columnWidths;
//根据设置添加新列,将对应新列的标题名称和宽度按照索引位置插
if (insertColumnIndex >= 0) {
columnCount++;
columnNames.insert(insertColumnIndex, insertColumnName);
columnWidths.insert(insertColumnIndex, insertColumnWidth);
queryModel->insertColumn(insertColumnIndex);
}
//设置列标题和列宽度
for (int i = 0; i < columnCount; i++) {
queryModel->setHeaderData(i, Qt::Horizontal, columnNames.at(i));
tableView->setColumnWidth(i, columnWidths.at(i));
}
if (labPageCurrent != 0) {
labPageCurrent->setText(QString("第 %1 页").arg(pageCurrent));
}
if (labPageTotal != 0) {
labPageTotal->setText(QString("共 %1 页").arg(pageTotal));
}
if (labRecordsTotal != 0) {
labRecordsTotal->setText(QString("共 %1 条").arg(recordsTotal));
}
if (labRecordsPerpage != 0) {
labRecordsPerpage->setText(QString("每页 %1 条").arg(recordsPerpage));
}
if (labSelectInfo != 0) {
//labSelectInfo->setText(QString("共 %1 条 每页 %2 条 共 %3 页 第 %4 页").arg(recordsTotal).arg(recordsPerpage).arg(pageTotal).arg(pageCurrent));
labSelectInfo->setText(QString("第 %1 页 每页 %2 条 共 %3 页 共 %4 条").arg(pageCurrent).arg(recordsPerpage).arg(pageTotal).arg(recordsTotal));
}
//发送结果信号
if (recordsTotal != recordsPerpage) {
emit receivePage(pageCurrent, pageTotal, recordsTotal, recordsPerpage);
//qDebug() << TIMEMS << startIndex << pageCurrent << pageTotal << recordsTotal << recordsPerpage;
}
changeBtnEnable();
}
QString DbPage::getPageSql()
{
//组织分页SQL语句,不同的数据库分页语句不一样
QString sql = QString("select %1 from %2 %3 order by %4").arg(selectColumn).arg(tableName).arg(whereSql).arg(orderSql);
if (dbType == DbType_PostgreSQL || dbType == DbType_KingBase) {
sql = QString("%1 limit %3 offset %2;").arg(sql).arg(startIndex).arg(recordsPerpage);
} else if (dbType == DbType_SqlServer) {
//取第m条到第n条记录select top (n-m+1) id from tablename where id not in (select top m-1 id from tablename)
//sql = QString("select %1 from %2 %3 order by %4").arg(selectColumn).arg(tableName).arg(whereSql).arg(orderSql);
} else if (dbType == DbType_Oracle) {
//暂时没有找到好办法
} else {
sql = QString("%1 limit %2,%3;").arg(sql).arg(startIndex).arg(recordsPerpage);
}
return sql;
}
void DbPage::slot_receiveCount(quint32 count, double msec)
{
if (labSelectTime != 0) {
labSelectTime->setText(QString("查询用时 %1 秒").arg(QString::number(msec / 1000, 'f', 3)));
}
recordsTotal = count;
int yushu = recordsTotal % recordsPerpage;
//不存在余数,说明是整行,例如300%5==0
if (yushu == 0) {
if (recordsTotal > 0 && recordsTotal < recordsPerpage) {
pageTotal = 1;
} else {
pageTotal = recordsTotal / recordsPerpage;
}
} else {
pageTotal = (recordsTotal / recordsPerpage) + 1;
}
bindData(getPageSql());
}
//设置显示数据的表格控件,当前翻页信息的标签控件等
void DbPage::setControl(QTableView *tableView,
QLabel *labPageTotal, QLabel *labPageCurrent,
QLabel *labRecordsTotal, QLabel *labRecordsPerpage,
QLabel *labSelectTime, QLabel *labSelectInfo,
QAbstractButton *btnFirst, QAbstractButton *btnPrevious,
QAbstractButton *btnNext, QAbstractButton *btnLast,
const QString &countName, const QString &connName)
{
this->tableView = tableView;
this->labPageTotal = labPageTotal;
this->labPageCurrent = labPageCurrent;
this->labRecordsTotal = labRecordsTotal;
this->labRecordsPerpage = labRecordsPerpage;
this->labSelectTime = labSelectTime;
this->labSelectInfo = labSelectInfo;
this->btnFirst = btnFirst;
this->btnPrevious = btnPrevious;
this->btnNext = btnNext;
this->btnLast = btnLast;
this->countName = countName;
this->connName = connName;
this->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
if (btnFirst == 0 || btnPrevious == 0 || btnNext == 0 || btnLast == 0) {
return;
}
//挂载翻页按钮事件
connect(btnFirst, SIGNAL(clicked()), this, SLOT(first()));
connect(btnPrevious, SIGNAL(clicked()), this, SLOT(previous()));
connect(btnNext, SIGNAL(clicked()), this, SLOT(next()));
connect(btnLast, SIGNAL(clicked()), this, SLOT(last()));
}
void DbPage::setControl(QTableView *tableView,
QLabel *labPageTotal, QLabel *labPageCurrent,
QLabel *labRecordsTotal, QLabel *labRecordsPerpage,
QLabel *labSelectTime, QLabel *labSelectInfo,
const QString &countName, const QString &connName)
{
setControl(tableView, labPageTotal, labPageCurrent, labRecordsTotal, labRecordsPerpage, labSelectTime, labSelectInfo, 0, 0, 0, 0, countName, connName);
}
void DbPage::setControl(QTableView *tableView,
QAbstractButton *btnFirst, QAbstractButton *btnPrevious,
QAbstractButton *btnNext, QAbstractButton *btnLast,
const QString &countName, const QString &connName)
{
setControl(tableView, 0, 0, 0, 0, 0, 0, btnFirst, btnPrevious, btnNext, btnLast, countName, connName);
}
void DbPage::setControl(QTableView *tableView, const QString &countName, const QString &connName)
{
setControl(tableView, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, countName, connName);
}
void DbPage::setConnName(const QString &connName)
{
this->connName = connName;
}
void DbPage::setDbType(const DbPage::DbType &dbType)
{
this->dbType = dbType;
}
void DbPage::setTableName(const QString &tableName)
{
this->tableName = tableName;
}
void DbPage::setSelectColumn(const QString &selectColumn)
{
this->selectColumn = selectColumn;
}
void DbPage::setOrderSql(const QString &orderSql)
{
this->orderSql = orderSql;
}
void DbPage::setWhereSql(const QString &whereSql)
{
this->whereSql = whereSql;
}
void DbPage::setRecordsPerpage(int recordsPerpage)
{
this->recordsPerpage = recordsPerpage;
}
void DbPage::setColumnNames(const QList<QString> &columnNames)
{
this->columnNames = columnNames;
}
void DbPage::setColumnWidths(const QList<int> &columnWidths)
{
this->columnWidths = columnWidths;
}
void DbPage::setAllCenter(bool allCenter)
{
queryModel->setAllCenter(allCenter);
}
void DbPage::setAlignCenterColumn(const QList<int> &alignCenterColumn)
{
queryModel->setAlignCenterColumn(alignCenterColumn);
}
void DbPage::setAlignRightColumn(const QList<int> &alignRightColumn)
{
queryModel->setAlignRightColumn(alignRightColumn);
}
void DbPage::setInsertColumnIndex(int insertColumnIndex)
{
this->insertColumnIndex = insertColumnIndex;
}
void DbPage::setInsertColumnName(const QString &insertColumnName)
{
this->insertColumnName = insertColumnName;
}
void DbPage::setInsertColumnWidth(int insertColumnWidth)
{
this->insertColumnWidth = insertColumnWidth;
}
void DbPage::changeBtnEnable()
{
if (btnFirst == 0 || btnPrevious == 0 || btnNext == 0 || btnLast == 0) {
return;
}
//下面默认对上一页下一页按钮禁用
//也可以取消注释对第一页末一页同样处理
//因为到了第一页就可以不必再单击第一页和上一页
if (pageTotal <= 1) {
//如果只有一页数据则翻页按钮不可用
btnFirst->setEnabled(false);
btnLast->setEnabled(false);
btnPrevious->setEnabled(false);
btnNext->setEnabled(false);
} else {
//判断是否在首页末页禁用按钮
bool first = (pageCurrent == 1);
bool last = (pageCurrent == pageTotal);
btnFirst->setEnabled(!first);
btnLast->setEnabled(!last);
btnPrevious->setEnabled(!first);
btnNext->setEnabled(!last);
}
}
void DbPage::select()
{
//重置开始索引
startIndex = 0;
pageCurrent = 1;
pageTotal = 1;
changeBtnEnable();
//假设只有一页
slot_receiveCount(recordsPerpage, 0);
//文本显示正在查询...
QString info = "正在查询...";
if (labSelectInfo != 0) {
labSelectInfo->setText(info);
}
if (labPageCurrent != 0) {
labPageCurrent->setText(info);
}
if (labPageTotal != 0) {
labPageTotal->setText(info);
}
if (labRecordsTotal != 0) {
labRecordsTotal->setText(info);
}
if (labRecordsPerpage != 0) {
labRecordsPerpage->setText(info);
}
if (labSelectTime != 0) {
labSelectTime->setText(info);
}
//开始分页绑定数据前,计算好总数据量以及行数
QString sql = QString("select count(%1) from %2 %3").arg(countName).arg(tableName).arg(whereSql);
//采用线程执行查询复合条件的记录行数
DbCountThread *dbCountThread = new DbCountThread(this);
//绑定查询结果信号槽,一旦收到结果则立即执行
connect(dbCountThread, SIGNAL(receiveCount(quint32, double)), this, SIGNAL(receiveCount(quint32, double)));
connect(dbCountThread, SIGNAL(receiveCount(quint32, double)), this, SLOT(slot_receiveCount(quint32, double)));
//设置数据库连接名称和查询语句,并启动线程
dbCountThread->setConnName(connName);
dbCountThread->setSql(sql);
//从5.10开始不支持数据库在线程中执行
#if (QT_VERSION <= QT_VERSION_CHECK(5,10,0))
dbCountThread->start();
#else
dbCountThread->select();
#endif
}
void DbPage::selectPage(int page)
{
//必须小于总页数+不是当前页
if (page >= 1 && page <= pageTotal && page != pageCurrent) {
//计算指定页对应开始的索引
startIndex = (page - 1) * recordsPerpage;
pageCurrent = page;
bindData(getPageSql());
}
}
void DbPage::first()
{
//当前页不是第一页才能切换到第一页
if (pageTotal > 1 && pageCurrent != 1) {
startIndex = 0;
pageCurrent = 1;
bindData(getPageSql());
}
}
void DbPage::previous()
{
//当前页不是第一页才能上一页
if (pageCurrent > 1) {
pageCurrent--;
startIndex -= recordsPerpage;
bindData(getPageSql());
}
}
void DbPage::next()
{
//当前页小于总页数才能下一页
if (pageCurrent < pageTotal) {
pageCurrent++;
startIndex += recordsPerpage;
bindData(getPageSql());
}
}
void DbPage::last()
{
//当前页不是末尾页才能切换到末尾页
if (pageTotal > 1 && pageCurrent != pageTotal) {
startIndex = (pageTotal - 1) * recordsPerpage;
pageCurrent = pageTotal;
bindData(getPageSql());
}
}

217
other/dbpage/dbpage.h Normal file
View File

@@ -0,0 +1,217 @@
#ifndef DBPAGE_H
#define DBPAGE_H
/**
* 数据库通用翻页类 作者:feiyangqingyun(QQ:517216493) 2017-1-15
* 1:自动按照设定的每页多少行数据分页
* 2:只需要传入表名/字段集合/每页行数/翻页指示按钮/文字指示标签
* 3:提供公共静态方法绑定字段数据到下拉框
* 4:建议条件字段用数字类型的主键,速度极快
* 5:增加线程查询符合条件的记录总数,数据量巨大时候不会卡主界面
* 6:提供查询结果返回信号,包括当前页/总页数/总记录数/查询用时
* 7:可设置所有列或者某一列对齐样式例如居中或者右对齐
* 8:可设置增加一列,列的位置,标题,宽度
* 9:可设置要查询的字段集合
*/
#include <QtGui>
#include <QtSql>
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
#include <QtWidgets>
#endif
//自定义模型设置列居中和右对齐
class SqlQueryModel: public QSqlQueryModel
{
public:
explicit SqlQueryModel(QObject *parent = 0);
protected:
QVariant data(const QModelIndex &index, int role) const;
private:
bool allCenter; //所有居中
QList<int> alignCenterColumn; //居中对齐列
QList<int> alignRightColumn; //右对齐列
public:
//设置所有列居中
void setAllCenter(bool allCenter);
//设置居中对齐列索引集合
void setAlignCenterColumn(const QList<int> &alignCenterColumn);
//设置右对齐列索引集合
void setAlignRightColumn(const QList<int> &alignRightColumn);
};
//计算复合条件的记录总行数,以便分页
class DbCountThread : public QThread
{
Q_OBJECT
public:
explicit DbCountThread(QObject *parent = 0);
private:
QString connName; //数据库连接名称
QString sql; //要执行的查询语句
protected:
void run();
signals:
void receiveCount(quint32 count, double msec);
public slots:
//设置数据库连接名称
void setConnName(const QString &connName);
//设置要执行的查询语句
void setSql(const QString &sql);
//查询行数
void select();
};
class DbPage : public QObject
{
Q_OBJECT
public:
enum DbType {
DbType_ODBC = 0, //odbc数据源
DbType_Sqlite = 1, //sqlite数据库
DbType_MySql = 2, //mysql数据库
DbType_PostgreSQL = 3, //postgresql数据库
DbType_SqlServer = 4, //sqlserver数据库
DbType_Oracle = 5, //oracle数据库
DbType_KingBase = 6, //人大金仓数据库
DbType_Other = 255 //其他数据库
};
explicit DbPage(QObject *parent = 0);
//绑定数据到下拉框
static void bindData(const QString &columnName, const QString &orderColumn, const QString &tableName,
QComboBox *cbox, const QString &connName = "qt_sql_default_connection");
static void bindData(const QString &columnName, const QString &orderColumn, const QString &tableName,
QList<QComboBox *> cboxs, const QString &connName = "qt_sql_default_connection");
private:
int startIndex; //分页开始索引,每次翻页都变动
SqlQueryModel *queryModel; //查询模型
QLabel *labPageTotal; //总页数标签
QLabel *labPageCurrent; //当前页标签
QLabel *labRecordsTotal; //总记录数标签
QLabel *labRecordsPerpage; //每页记录数标签
QLabel *labSelectTime; //显示查询用时标签
QLabel *labSelectInfo; //总页数当前页总记录数每页记录数
QTableView *tableView; //显示数据的表格对象
QAbstractButton *btnFirst; //第一页按钮对象
QAbstractButton *btnPrevious;//上一页按钮对象
QAbstractButton *btnNext; //下一页按钮对象
QAbstractButton *btnLast; //末一页按钮对象
QString countName; //统计表行数用字段
QString connName; //所使用的数据库连接名
DbType dbType; //数据库类型
quint32 pageCurrent; //当前第几页
quint32 pageTotal; //总页数
quint32 recordsTotal; //总记录数
quint32 recordsPerpage; //每页显示记录数
QString tableName; //表名
QString selectColumn; //要查询的字段集合
QString orderSql; //排序语句
QString whereSql; //条件语句
QList<QString> columnNames; //列名集合
QList<int> columnWidths; //列宽集合
int insertColumnIndex; //插入的列的索引位置
QString insertColumnName; //插入的列的标题
int insertColumnWidth; //插入的列的宽度
private slots:
//绑定sql语句到表格
void bindData(const QString &sql);
//生成分页sql语句
QString getPageSql();
//收到记录行数
void slot_receiveCount(quint32 count, double msec);
signals:
//将翻页后的页码信息发出去可能其他地方要用到
void receivePage(quint32 pageCurrent, quint32 pageTotal, quint32 recordsTotal, quint32 recordsPerpage);
void receiveCount(quint32 count, double msec);
public slots:
//设置需要显示数据的表格,数据翻页对应的按钮
void setControl(QTableView *tableView,
QLabel *labPageTotal, QLabel *labPageCurrent,
QLabel *labRecordsTotal, QLabel *labRecordsPerpage,
QLabel *labSelectTime, QLabel *labSelectInfo,
QAbstractButton *btnFirst, QAbstractButton *btnPrevious,
QAbstractButton *btnNext, QAbstractButton *btnLast,
const QString &countName, const QString &connName = "qt_sql_default_connection");
void setControl(QTableView *tableView,
QLabel *labPageTotal, QLabel *labPageCurrent,
QLabel *labRecordsTotal, QLabel *labRecordsPerpage,
QLabel *labSelectTime, QLabel *labSelectInfo,
const QString &countName, const QString &connName = "qt_sql_default_connection");
void setControl(QTableView *tableView,
QAbstractButton *btnFirst, QAbstractButton *btnPrevious,
QAbstractButton *btnNext, QAbstractButton *btnLast,
const QString &countName, const QString &connName = "qt_sql_default_connection");
void setControl(QTableView *tableView,
const QString &countName, const QString &connName = "qt_sql_default_connection");
//设置数据库连接名称
void setConnName(const QString &connName);
//设置数据库类型
void setDbType(const DbType &dbType);
//设置要查询的表名
void setTableName(const QString &tableName);
//设置要查询的字段列名集合
void setSelectColumn(const QString &selectColumn);
//设置排序sql
void setOrderSql(const QString &orderSql);
//设置条件sql
void setWhereSql(const QString &whereSql);
//设置每页显示多少行数据
void setRecordsPerpage(int recordsPerpage);
//设置列名称集合
void setColumnNames(const QList<QString> &columnNames);
//设置列宽度集合
void setColumnWidths(const QList<int> &columnWidths);
//设置所有列居中
void setAllCenter(bool allCenter);
//设置居中对齐列索引集合
void setAlignCenterColumn(const QList<int> &alignCenterColumn);
//设置右对齐列索引集合
void setAlignRightColumn(const QList<int> &alignRightColumn);
//设置插入的列的索引
void setInsertColumnIndex(int insertColumnIndex);
//设置插入的列的标题
void setInsertColumnName(const QString &insertColumnName);
//设置插入的列的宽度
void setInsertColumnWidth(int insertColumnWidth);
//根据首页末页禁用按钮
void changeBtnEnable();
//执行查询
void select();
//指定页跳转
void selectPage(int page);
//翻页 第一页+上一页+下一页+末一页
void first();
void previous();
void next();
void last();
};
#endif // DBPAGE_H

30
other/dbpage/dbpage.pro Normal file
View File

@@ -0,0 +1,30 @@
QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
TARGET = dbpage
TEMPLATE = app
DESTDIR = $$PWD/../bin
CONFIG += warn_off
SOURCES += main.cpp
SOURCES += dbpage.cpp
SOURCES += frmdbpage.cpp
HEADERS += dbpage.h
HEADERS += frmdbpage.h
FORMS += frmdbpage.ui
#自动拷贝文件
src_file = $$PWD/TA.db
dst_file = $$DESTDIR
win32 {
#转换斜杠 / \\
src_file ~= s,/,\\,g
dst_file ~= s,/,\\,g
dst_file2 ~= s,/,\\,g
QMAKE_POST_LINK += copy $$src_file $$dst_file
}
unix {
QMAKE_POST_LINK += cp -r -f $$src_file $$dst_file
}

View File

@@ -0,0 +1,66 @@
#include "frmdbpage.h"
#include "ui_frmdbpage.h"
#include "dbpage.h"
frmDbPage::frmDbPage(QWidget *parent) : QWidget(parent), ui(new Ui::frmDbPage)
{
ui->setupUi(this);
this->initForm();
on_btnSelect_clicked();
}
frmDbPage::~frmDbPage()
{
delete ui;
}
void frmDbPage::initForm()
{
columnNames.clear();
columnWidths.clear();
tableName = "LogInfo";
countName = "rowid";
columnNames.append("防区号");
columnNames.append("防区名称");
columnNames.append("设备IP");
columnNames.append("日志类型");
columnNames.append("事件内容");
columnNames.append("触发时间");
columnNames.append("告警详情");
columnNames.append("告警数据");
columnNames.append("告警图像");
columnWidths.append(70);
columnWidths.append(120);
columnWidths.append(120);
columnWidths.append(80);
columnWidths.append(150);
columnWidths.append(160);
columnWidths.append(160);
columnWidths.append(160);
columnWidths.append(160);
//设置需要显示数据的表格和翻页的按钮
dbPage = new DbPage(this);
//设置所有列居中显示
dbPage->setAllCenter(true);
dbPage->setControl(ui->tableMain, ui->labPageTotal, ui->labPageCurrent, ui->labRecordsTotal, ui->labRecordsPerpage,
ui->labSelectTime, 0, ui->btnFirst, ui->btnPreVious, ui->btnNext, ui->btnLast, countName);
ui->tableMain->horizontalHeader()->setStretchLastSection(true);
ui->tableMain->verticalHeader()->setDefaultSectionSize(25);
}
void frmDbPage::on_btnSelect_clicked()
{
//绑定数据到表格
QString sql = "where 1=1";
dbPage->setTableName(tableName);
dbPage->setOrderSql(QString("%1 %2").arg(countName).arg("asc"));
dbPage->setWhereSql(sql);
dbPage->setRecordsPerpage(20);
dbPage->setColumnNames(columnNames);
dbPage->setColumnWidths(columnWidths);
dbPage->select();
}

37
other/dbpage/frmdbpage.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef FRMDBPAGE_H
#define FRMDBPAGE_H
#include <QWidget>
class DbPage;
namespace Ui {
class frmDbPage;
}
class frmDbPage : public QWidget
{
Q_OBJECT
public:
explicit frmDbPage(QWidget *parent = 0);
~frmDbPage();
private:
Ui::frmDbPage *ui;
QList<QString> columnNames; //字段名集合
QList<int> columnWidths; //字段宽度集合
DbPage *dbPage; //数据库翻页类
QString tableName; //表名称
QString countName; //统计行数字段名称
private slots:
void initForm();
private slots:
void on_btnSelect_clicked();
};
#endif // FRMDBPAGE_H

296
other/dbpage/frmdbpage.ui Normal file
View File

@@ -0,0 +1,296 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmDbPage</class>
<widget class="QWidget" name="frmDbPage">
<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="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="opaqueResize">
<bool>false</bool>
</property>
<widget class="QTableView" name="tableMain">
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frameBottom">
<property name="minimumSize">
<size>
<width>190</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>190</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">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="btnSelect">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>查询</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnPreVious">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>上一页</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnNext">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>下一页</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnFirst">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>第一页</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnLast">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>末一页</string>
</property>
<property name="iconSize">
<size>
<width>18</width>
<height>18</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labPageTotal">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</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>
<widget class="QLabel" name="labRecordsTotal">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</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>
<widget class="QLabel" name="labPageCurrent">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</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>
<widget class="QLabel" name="labRecordsPerpage">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</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>
<widget class="QLabel" name="labSelectTime">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</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>
<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>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

8
other/dbpage/head.h Normal file
View File

@@ -0,0 +1,8 @@
#include <QtCore>
#include <QtGui>
#include <QtSql>
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
#include <QtWidgets>
#endif
#pragma execution_character_set("utf-8")

41
other/dbpage/main.cpp Normal file
View File

@@ -0,0 +1,41 @@
#include "frmdbpage.h"
#include "qapplication.h"
#include "qtextcodec.h"
#include "qsqldatabase.h"
#include "qsqlquery.h"
#include "qdebug.h"
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
//打开数据库,整个应用程序可用
QSqlDatabase dbConn = QSqlDatabase::addDatabase("QSQLITE");
dbConn.setDatabaseName(qApp->applicationDirPath() + "/TA.db");
if (dbConn.open()) {
qDebug() << "连接数据库成功!";
} else {
qDebug() << "连接数据库失败!";
}
frmDbPage w;
w.setWindowTitle("数据库分页示例(作者:517216493)");
w.show();
return a.exec();
}

1
other/dbpage/readme.txt Normal file
View File

@@ -0,0 +1 @@
<EFBFBD>ǵý<EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>TA.db<64><62><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD>ļ<EFBFBD>ͬһĿ¼

View File

@@ -0,0 +1,28 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4) QT += widgets
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
TARGET = echartgauge
TEMPLATE = app
DESTDIR = $$PWD/../bin
SOURCES += main.cpp
SOURCES += widget.cpp
HEADERS += widget.h
FORMS += widget.ui
include ($$PWD/webcore.pri)
#自动拷贝文件
src_file = $$PWD/file/*
dst_file = $$DESTDIR
win32 {
#转换斜杠 / 到 \\
src_file ~= s,/,\\,g
dst_file ~= s,/,\\,g
dst_file2 ~= s,/,\\,g
QMAKE_POST_LINK += copy $$src_file $$dst_file
}
unix {
QMAKE_POST_LINK += cp -r -f $$src_file $$dst_file
}

32
other/echartgauge/file/echarts.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<script src="echarts.min.js"></script>
</head>
<body>
<div id="main" style="height:300px;"></div>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
function setGaugeValue(value){
var option = {
tooltip : {
formatter: "{a} <br/>{b} : {c}%"
},
toolbox: {
feature: {
restore: {},
saveAsImage: {}
}
},
series: [
{
name: '业务指标',
type: 'gauge',
detail: {formatter:'{value}%'},
data: [{value: value, name: '完成率'}]
}
]
};
myChart.setOption(option);
}
window.onresize = myChart.resize;
setGaugeValue(68);
</script>
</body>
</html>

View File

@@ -0,0 +1,430 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebChannel module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
"use strict";
var QWebChannelMessageTypes = {
signal: 1,
propertyUpdate: 2,
init: 3,
idle: 4,
debug: 5,
invokeMethod: 6,
connectToSignal: 7,
disconnectFromSignal: 8,
setProperty: 9,
response: 10,
};
var QWebChannel = function(transport, initCallback)
{
if (typeof transport !== "object" || typeof transport.send !== "function") {
console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." +
" Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send));
return;
}
var channel = this;
this.transport = transport;
this.send = function(data)
{
if (typeof(data) !== "string") {
data = JSON.stringify(data);
}
channel.transport.send(data);
}
this.transport.onmessage = function(message)
{
var data = message.data;
if (typeof data === "string") {
data = JSON.parse(data);
}
switch (data.type) {
case QWebChannelMessageTypes.signal:
channel.handleSignal(data);
break;
case QWebChannelMessageTypes.response:
channel.handleResponse(data);
break;
case QWebChannelMessageTypes.propertyUpdate:
channel.handlePropertyUpdate(data);
break;
default:
console.error("invalid message received:", message.data);
break;
}
}
this.execCallbacks = {};
this.execId = 0;
this.exec = function(data, callback)
{
if (!callback) {
// if no callback is given, send directly
channel.send(data);
return;
}
if (channel.execId === Number.MAX_VALUE) {
// wrap
channel.execId = Number.MIN_VALUE;
}
if (data.hasOwnProperty("id")) {
console.error("Cannot exec message with property id: " + JSON.stringify(data));
return;
}
data.id = channel.execId++;
channel.execCallbacks[data.id] = callback;
channel.send(data);
};
this.objects = {};
this.handleSignal = function(message)
{
var object = channel.objects[message.object];
if (object) {
object.signalEmitted(message.signal, message.args);
} else {
console.warn("Unhandled signal: " + message.object + "::" + message.signal);
}
}
this.handleResponse = function(message)
{
if (!message.hasOwnProperty("id")) {
console.error("Invalid response message received: ", JSON.stringify(message));
return;
}
channel.execCallbacks[message.id](message.data);
delete channel.execCallbacks[message.id];
}
this.handlePropertyUpdate = function(message)
{
for (var i in message.data) {
var data = message.data[i];
var object = channel.objects[data.object];
if (object) {
object.propertyUpdate(data.signals, data.properties);
} else {
console.warn("Unhandled property update: " + data.object + "::" + data.signal);
}
}
channel.exec({type: QWebChannelMessageTypes.idle});
}
this.debug = function(message)
{
channel.send({type: QWebChannelMessageTypes.debug, data: message});
};
channel.exec({type: QWebChannelMessageTypes.init}, function(data) {
for (var objectName in data) {
var object = new QObject(objectName, data[objectName], channel);
}
// now unwrap properties, which might reference other registered objects
for (var objectName in channel.objects) {
channel.objects[objectName].unwrapProperties();
}
if (initCallback) {
initCallback(channel);
}
channel.exec({type: QWebChannelMessageTypes.idle});
});
};
function QObject(name, data, webChannel)
{
this.__id__ = name;
webChannel.objects[name] = this;
// List of callbacks that get invoked upon signal emission
this.__objectSignals__ = {};
// Cache of all properties, updated when a notify signal is emitted
this.__propertyCache__ = {};
var object = this;
// ----------------------------------------------------------------------
this.unwrapQObject = function(response)
{
if (response instanceof Array) {
// support list of objects
var ret = new Array(response.length);
for (var i = 0; i < response.length; ++i) {
ret[i] = object.unwrapQObject(response[i]);
}
return ret;
}
if (!response
|| !response["__QObject*__"]
|| response.id === undefined) {
return response;
}
var objectId = response.id;
if (webChannel.objects[objectId])
return webChannel.objects[objectId];
if (!response.data) {
console.error("Cannot unwrap unknown QObject " + objectId + " without data.");
return;
}
var qObject = new QObject( objectId, response.data, webChannel );
qObject.destroyed.connect(function() {
if (webChannel.objects[objectId] === qObject) {
delete webChannel.objects[objectId];
// reset the now deleted QObject to an empty {} object
// just assigning {} though would not have the desired effect, but the
// below also ensures all external references will see the empty map
// NOTE: this detour is necessary to workaround QTBUG-40021
var propertyNames = [];
for (var propertyName in qObject) {
propertyNames.push(propertyName);
}
for (var idx in propertyNames) {
delete qObject[propertyNames[idx]];
}
}
});
// here we are already initialized, and thus must directly unwrap the properties
qObject.unwrapProperties();
return qObject;
}
this.unwrapProperties = function()
{
for (var propertyIdx in object.__propertyCache__) {
object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]);
}
}
function addSignal(signalData, isPropertyNotifySignal)
{
var signalName = signalData[0];
var signalIndex = signalData[1];
object[signalName] = {
connect: function(callback) {
if (typeof(callback) !== "function") {
console.error("Bad callback given to connect to signal " + signalName);
return;
}
object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
object.__objectSignals__[signalIndex].push(callback);
if (!isPropertyNotifySignal && signalName !== "destroyed") {
// only required for "pure" signals, handled separately for properties in propertyUpdate
// also note that we always get notified about the destroyed signal
webChannel.exec({
type: QWebChannelMessageTypes.connectToSignal,
object: object.__id__,
signal: signalIndex
});
}
},
disconnect: function(callback) {
if (typeof(callback) !== "function") {
console.error("Bad callback given to disconnect from signal " + signalName);
return;
}
object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
var idx = object.__objectSignals__[signalIndex].indexOf(callback);
if (idx === -1) {
console.error("Cannot find connection of signal " + signalName + " to " + callback.name);
return;
}
object.__objectSignals__[signalIndex].splice(idx, 1);
if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) {
// only required for "pure" signals, handled separately for properties in propertyUpdate
webChannel.exec({
type: QWebChannelMessageTypes.disconnectFromSignal,
object: object.__id__,
signal: signalIndex
});
}
}
};
}
/**
* Invokes all callbacks for the given signalname. Also works for property notify callbacks.
*/
function invokeSignalCallbacks(signalName, signalArgs)
{
var connections = object.__objectSignals__[signalName];
if (connections) {
connections.forEach(function(callback) {
callback.apply(callback, signalArgs);
});
}
}
this.propertyUpdate = function(signals, propertyMap)
{
// update property cache
for (var propertyIndex in propertyMap) {
var propertyValue = propertyMap[propertyIndex];
object.__propertyCache__[propertyIndex] = propertyValue;
}
for (var signalName in signals) {
// Invoke all callbacks, as signalEmitted() does not. This ensures the
// property cache is updated before the callbacks are invoked.
invokeSignalCallbacks(signalName, signals[signalName]);
}
}
this.signalEmitted = function(signalName, signalArgs)
{
invokeSignalCallbacks(signalName, signalArgs);
}
function addMethod(methodData)
{
var methodName = methodData[0];
var methodIdx = methodData[1];
object[methodName] = function() {
var args = [];
var callback;
for (var i = 0; i < arguments.length; ++i) {
if (typeof arguments[i] === "function")
callback = arguments[i];
else
args.push(arguments[i]);
}
webChannel.exec({
"type": QWebChannelMessageTypes.invokeMethod,
"object": object.__id__,
"method": methodIdx,
"args": args
}, function(response) {
if (response !== undefined) {
var result = object.unwrapQObject(response);
if (callback) {
(callback)(result);
}
}
});
};
}
function bindGetterSetter(propertyInfo)
{
var propertyIndex = propertyInfo[0];
var propertyName = propertyInfo[1];
var notifySignalData = propertyInfo[2];
// initialize property cache with current value
// NOTE: if this is an object, it is not directly unwrapped as it might
// reference other QObject that we do not know yet
object.__propertyCache__[propertyIndex] = propertyInfo[3];
if (notifySignalData) {
if (notifySignalData[0] === 1) {
// signal name is optimized away, reconstruct the actual name
notifySignalData[0] = propertyName + "Changed";
}
addSignal(notifySignalData, true);
}
Object.defineProperty(object, propertyName, {
configurable: true,
get: function () {
var propertyValue = object.__propertyCache__[propertyIndex];
if (propertyValue === undefined) {
// This shouldn't happen
console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__);
}
return propertyValue;
},
set: function(value) {
if (value === undefined) {
console.warn("Property setter for " + propertyName + " called with undefined value!");
return;
}
object.__propertyCache__[propertyIndex] = value;
webChannel.exec({
"type": QWebChannelMessageTypes.setProperty,
"object": object.__id__,
"property": propertyIndex,
"value": value
});
}
});
}
// ----------------------------------------------------------------------
data.methods.forEach(addMethod);
data.properties.forEach(bindGetterSetter);
data.signals.forEach(function(signal) { addSignal(signal, false); });
for (var name in data.enums) {
object[name] = data.enums[name];
}
}
//required for use with nodejs
if (typeof module === 'object') {
module.exports = {
QWebChannel: QWebChannel
};
}

View File

@@ -0,0 +1,11 @@
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1 @@
<EFBFBD>뽫Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>file<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>

View File

@@ -0,0 +1,51 @@
#默认假定采用webkit,因为Qt4没有qtHaveModule函数而且默认采用的是webkit
#如果在windows上没有浏览器模块则默认采用miniblink
DEFINES += webkit
#判断当前qt版本号
message($$QT_ARCH : $$QT_VERSION -> $$QT_MAJOR_VERSION . $$QT_MINOR_VERSION)
#5.0以上版本
!lessThan(QT_MAJOR_VERSION, 5) {
#如果没有安装webkit模块
!qtHaveModule(webkit) {
DEFINES -= webkit
}
#如果安装了webenginewidgets模块
qtHaveModule(webenginewidgets) {
DEFINES += webengine
}
}
#6.0以上版本 强制使用miniblink
greaterThan(QT_MAJOR_VERSION, 5) {
#DEFINES -= webkit
#DEFINES += webminiblink
}
contains(DEFINES, webkit) {
QT += webkit
greaterThan(QT_MAJOR_VERSION, 4) {
QT += webkitwidgets
}
} else {
contains(DEFINES, webengine) {
QT += webenginewidgets
} else {
message("没有找到浏览器模块,将采用第三方浏览器模块哦")
#如果采用IE浏览器则改成 DEFINES += webie
#如果采用miniblink改成 DEFINES += webminiblink 只支持win
win32 {DEFINES += webminiblink}
greaterThan(QT_MAJOR_VERSION, 4) {
lessThan(QT_MAJOR_VERSION, 6) {
win32 {QT += axcontainer}
}
} else {
win32 {CONFIG += qaxcontainer}
}}}
#在win上也可以手动强制使用 miniblink 就算存在 webkit 或者 webengine
#DEFINES -= webkit
#DEFINES -= webengine
#DEFINES += webminiblink

View File

@@ -0,0 +1,79 @@
#include "widget.h"
#include "ui_widget.h"
#include "qurl.h"
#ifdef webkit
#include <QtWebKit>
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
#include <QtWebKitWidgets>
#endif
#elif webengine
#include <QtWebEngineWidgets>
#endif
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
this->initForm();
}
Widget::~Widget()
{
delete ui;
}
void Widget::initForm()
{
#ifdef webkit
QWebSettings *webSetting = QWebSettings::globalSettings();
webSetting->setAttribute(QWebSettings::JavascriptEnabled, true);
webSetting->setAttribute(QWebSettings::PluginsEnabled, true);
webSetting->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
#elif webengine
QWebEngineSettings *webSetting = QWebEngineProfile::defaultProfile()->settings();
webSetting->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
webSetting->setAttribute(QWebEngineSettings::PluginsEnabled, true);
webSetting->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
#endif
#ifdef webkit
webView = new QWebView;
webView1 = new QWebView;
webView2 = new QWebView;
webView3 = new QWebView;
#elif webengine
webView = new QWebEngineView;
webView1 = new QWebEngineView;
webView2 = new QWebEngineView;
webView3 = new QWebEngineView;
#endif
QUrl url("file:///" + qApp->applicationDirPath() + "/gauge.html");
#if (defined webkit) || (defined webengine)
ui->gridLayout->addWidget(webView, 0, 0);
ui->gridLayout->addWidget(webView1, 0, 1);
ui->gridLayout->addWidget(webView2, 1, 0);
ui->gridLayout->addWidget(webView3, 1, 1);
webView->load(url);
webView1->load(url);
webView2->load(url);
webView3->load(url);
#endif
}
void Widget::on_horizontalSlider_valueChanged(int value)
{
QString js = QString("setGaugeValue(%1)").arg(value);
#ifdef webkit
webView->page()->mainFrame()->evaluateJavaScript(js);
webView1->page()->mainFrame()->evaluateJavaScript(js);
webView2->page()->mainFrame()->evaluateJavaScript(js);
webView3->page()->mainFrame()->evaluateJavaScript(js);
#elif webengine
webView->page()->runJavaScript(js);
webView1->page()->runJavaScript(js);
webView2->page()->runJavaScript(js);
webView3->page()->runJavaScript(js);
#endif
}

View File

@@ -0,0 +1,33 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class QWebView;
class QWebEngineView;
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void initForm();
void on_horizontalSlider_valueChanged(int value);
private:
Ui::Widget *ui;
#ifdef webkit
QWebView *webView, *webView1, *webView2, *webView3;
#elif webengine
QWebEngineView *webView, *webView1, *webView2, *webView3;
#endif
};
#endif // WIDGET_H

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Echart图表JS交互示例</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout">
<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>
</layout>
</widget>
</item>
<item>
<widget class="QSlider" name="horizontalSlider">
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>68</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,13 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
TARGET = lineeditnext
TEMPLATE = app
DESTDIR = $$PWD/../bin
CONFIG += warn_off
SOURCES += main.cpp
SOURCES += widget.cpp
HEADERS += widget.h
FORMS += widget.ui

View File

@@ -0,0 +1,11 @@
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,30 @@
#include "widget.h"
#include "ui_widget.h"
#include "qlineedit.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->lineEdit1, SIGNAL(returnPressed()), this, SLOT(next()));
connect(ui->lineEdit2, SIGNAL(returnPressed()), this, SLOT(next()));
connect(ui->lineEdit3, SIGNAL(returnPressed()), this, SLOT(next()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::next()
{
QLineEdit *lineEdit = (QLineEdit *)sender();
if (lineEdit == ui->lineEdit1) {
ui->lineEdit2->setFocus();
} else if (lineEdit == ui->lineEdit2) {
ui->lineEdit3->setFocus();
} else if (lineEdit == ui->lineEdit3) {
ui->lineEdit1->setFocus();
}
}

View File

@@ -0,0 +1,25 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
private slots:
void next();
};
#endif // WIDGET_H

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>回车自动跳转</string>
</property>
<widget class="QLineEdit" name="lineEdit1">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>113</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit2">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>113</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit3">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>113</width>
<height>20</height>
</rect>
</property>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

11
other/mouseline/main.cpp Normal file
View File

@@ -0,0 +1,11 @@
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,13 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
TARGET = mouseline
TEMPLATE = app
DESTDIR = $$PWD/../bin
CONFIG += warn_off
SOURCES += main.cpp
SOURCES += widget.cpp
HEADERS += widget.h
FORMS += widget.ui

View File

@@ -0,0 +1,45 @@
#include "widget.h"
#include "ui_widget.h"
#include "qpainter.h"
#include "qevent.h"
#include "qdebug.h"
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
this->setMouseTracking(true);
}
Widget::~Widget()
{
delete ui;
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
lastPos = event->pos();
update();
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
//这里是鼠标按下的坐标,自己存到数据库
lastPos = event->pos();
update();
qDebug() << lastPos;
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPen pen;
pen.setWidth(5);
pen.setColor(Qt::red);
painter.setPen(pen);
//绘制横向线
painter.drawLine(0, lastPos.y(), width(), lastPos.y());
//绘制纵向线
painter.drawLine(lastPos.x(), 0, lastPos.x(), height());
}

28
other/mouseline/widget.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *);
private:
Ui::Widget *ui;
QPoint lastPos;
};
#endif // WIDGET_H

20
other/mouseline/widget.ui Normal file
View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>鼠标十字线</string>
</property>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,29 @@
#pragma execution_character_set("utf-8")
#include "frmntpclient.h"
#include "ui_frmntpclient.h"
#include "ntpclient.h"
#include "qdebug.h"
frmNtpClient::frmNtpClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmNtpClient)
{
ui->setupUi(this);
ui->txtNtpIP->setText("ntp1.aliyun.com");
connect(NtpClient::Instance(), SIGNAL(receiveTime(QDateTime)), this, SLOT(receiveTime(QDateTime)));
}
frmNtpClient::~frmNtpClient()
{
delete ui;
}
void frmNtpClient::on_btnGetTime_clicked()
{
NtpClient::Instance()->setNtpIP(ui->txtNtpIP->text().trimmed());
NtpClient::Instance()->getDateTime();
}
void frmNtpClient::receiveTime(const QDateTime &dateTime)
{
ui->txtTime->setText(dateTime.toString("yyyy-MM-dd HH:mm:ss zzz"));
}

View File

@@ -0,0 +1,27 @@
#ifndef FRMNTPCLIENT_H
#define FRMNTPCLIENT_H
#include <QWidget>
#include <QDateTime>
namespace Ui {
class frmNtpClient;
}
class frmNtpClient : public QWidget
{
Q_OBJECT
public:
explicit frmNtpClient(QWidget *parent = 0);
~frmNtpClient();
private:
Ui::frmNtpClient *ui;
private slots:
void on_btnGetTime_clicked();
void receiveTime(const QDateTime &dateTime);
};
#endif // FRMNTPCLIENT_H

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmNtpClient</class>
<widget class="QWidget" name="frmNtpClient">
<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>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>381</width>
<height>51</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="labNtpIP">
<property name="text">
<string>服务地址</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="txtNtpIP">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<widget class="QPushButton" name="btnGetTime">
<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 row="1" column="0">
<widget class="QLabel" name="labTime">
<property name="text">
<string>返回时间</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="txtTime"/>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>

31
other/ntpclient/main.cpp Normal file
View File

@@ -0,0 +1,31 @@
#pragma execution_character_set("utf-8")
#include "frmntpclient.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
frmNtpClient w;
w.setWindowTitle("Ntp校时");
w.show();
return a.exec();
}

View File

@@ -0,0 +1,119 @@
#include "ntpclient.h"
#include "qmutex.h"
#include "qudpsocket.h"
#include "qdebug.h"
QScopedPointer<NtpClient> NtpClient::self;
NtpClient *NtpClient::Instance()
{
if (self.isNull()) {
static QMutex mutex;
QMutexLocker locker(&mutex);
if (self.isNull()) {
self.reset(new NtpClient);
}
}
return self.data();
}
NtpClient::NtpClient(QObject *parent) : QObject(parent)
{
ntpIP = "ntp1.aliyun.com";
udpSocket = new QUdpSocket(this);
connect(udpSocket, SIGNAL(connected()), this, SLOT(sendData()));
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readData()));
}
void NtpClient::sendData()
{
qint8 LI = 0;
qint8 VN = 3;
qint8 MODE = 3;
qint8 STRATUM = 0;
qint8 POLL = 4;
qint8 PREC = -6;
QDateTime epoch(QDate(1900, 1, 1), QTime(0, 0, 0));
qint32 second = quint32(epoch.secsTo(QDateTime::currentDateTime()));
qint32 temp = 0;
QByteArray timeRequest(48, 0);
timeRequest[0] = (LI << 6) | (VN << 3) | (MODE);
timeRequest[1] = STRATUM;
timeRequest[2] = POLL;
timeRequest[3] = PREC & 0xff;
timeRequest[5] = 1;
timeRequest[9] = 1;
timeRequest[40] = (temp = (second & 0xff000000) >> 24);
temp = 0;
timeRequest[41] = (temp = (second & 0x00ff0000) >> 16);
temp = 0;
timeRequest[42] = (temp = (second & 0x0000ff00) >> 8);
temp = 0;
timeRequest[43] = ((second & 0x000000ff));
udpSocket->write(timeRequest);
}
void NtpClient::setTime_t(uint secsSince1Jan1970UTC)
{
}
void NtpClient::readData()
{
QByteArray newTime;
QDateTime epoch(QDate(1900, 1, 1), QTime(0, 0, 0));
QDateTime unixStart(QDate(1970, 1, 1), QTime(0, 0, 0));
while (udpSocket->hasPendingDatagrams()) {
newTime.resize(udpSocket->pendingDatagramSize());
udpSocket->read(newTime.data(), newTime.size());
};
QByteArray transmitTimeStamp ;
transmitTimeStamp = newTime.right(8);
quint32 seconds = transmitTimeStamp.at(0);
quint8 temp = 0;
for (int i = 1; i <= 3; i++) {
seconds = (seconds << 8);
temp = transmitTimeStamp.at(i);
seconds = seconds + temp;
}
QDateTime dateTime;
uint secs = seconds - epoch.secsTo(unixStart);
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
dateTime.setSecsSinceEpoch(secs);
#else
dateTime.setTime_t(secs);
#endif
#ifdef __arm__
#ifdef arma9
dateTime = dateTime.addSecs(8 * 60 * 60);
#endif
#endif
udpSocket->disconnectFromHost();
//有些时候返回的数据可能有误或者解析不正确,导致填充的时间不正确
if (dateTime.isValid()) {
emit receiveTime(dateTime);
}
}
void NtpClient::setNtpIP(const QString &ntpIP)
{
if (this->ntpIP != ntpIP) {
this->ntpIP = ntpIP;
}
}
void NtpClient::getDateTime()
{
udpSocket->abort();
udpSocket->connectToHost(ntpIP, 123);
}

View File

@@ -0,0 +1,49 @@
#ifndef NTPCLIENT_H
#define NTPCLIENT_H
/**
* Ntp校时类 作者:feiyangqingyun(QQ:517216493) 2017-02-16
* 1. 可设置Ntp服务器IP地址。
* 2. 推荐用默认的阿里云时间服务器 ntp1.aliyun.com
* 3. 收到时间信号发出。
* 4. 时间精确到秒。
*/
#include <QObject>
#include <QDateTime>
class QUdpSocket;
#ifdef quc
class Q_DECL_EXPORT NtpClient : public QObject
#else
class NtpClient : public QObject
#endif
{
Q_OBJECT
public:
static NtpClient *Instance();
explicit NtpClient(QObject *parent = 0);
private:
static QScopedPointer<NtpClient> self;
QString ntpIP;
QUdpSocket *udpSocket;
private slots:
void readData();
void sendData();
void setTime_t(uint secsSince1Jan1970UTC);
public Q_SLOTS:
//设置Ntp服务器IP
void setNtpIP(const QString &ntpIP);
//获取日期时间
void getDateTime();
Q_SIGNALS:
//收到时间返回
void receiveTime(const QDateTime &dateTime);
};
#endif // NTPCLIENT_H

View File

@@ -0,0 +1,17 @@
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
TARGET = ntpclient
TEMPLATE = app
DESTDIR = $$PWD/../bin
CONFIG += warn_off
SOURCES += main.cpp
SOURCES += frmntpclient.cpp
SOURCES += ntpclient.cpp
HEADERS += frmntpclient.h
HEADERS += ntpclient.h
FORMS += frmntpclient.ui

8
other/other.pro Normal file
View File

@@ -0,0 +1,8 @@
TEMPLATE = subdirs
SUBDIRS += bgdemo
SUBDIRS += dbpage
SUBDIRS += lineeditnext
SUBDIRS += mouseline
SUBDIRS += ntpclient
SUBDIRS += trayicon
SUBDIRS += echartgauge

View File

@@ -0,0 +1,27 @@
#include "frmtrayicon.h"
#include "ui_frmtrayicon.h"
#include "trayicon.h"
frmTrayIcon::frmTrayIcon(QWidget *parent) : QWidget(parent), ui(new Ui::frmTrayIcon)
{
ui->setupUi(this);
TrayIcon::Instance()->setIcon(":/main.ico");
TrayIcon::Instance()->setMainWidget(this);
}
frmTrayIcon::~frmTrayIcon()
{
TrayIcon::Instance()->setVisible(false);
delete ui;
}
void frmTrayIcon::on_btnShow_clicked()
{
TrayIcon::Instance()->setVisible(true);
TrayIcon::Instance()->showMessage("自定义控件大全", "已经最小化到托盘,双击打开!");
}
void frmTrayIcon::on_btnHide_clicked()
{
TrayIcon::Instance()->setVisible(false);
}

View File

@@ -0,0 +1,26 @@
#ifndef FRMTRAYICON_H
#define FRMTRAYICON_H
#include <QWidget>
namespace Ui {
class frmTrayIcon;
}
class frmTrayIcon : public QWidget
{
Q_OBJECT
public:
explicit frmTrayIcon(QWidget *parent = 0);
~frmTrayIcon();
private:
Ui::frmTrayIcon *ui;
private slots:
void on_btnShow_clicked();
void on_btnHide_clicked();
};
#endif // FRMTRAYICON_H

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmTrayIcon</class>
<widget class="QWidget" name="frmTrayIcon">
<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>
<widget class="QPushButton" name="btnShow">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>92</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>显示托盘</string>
</property>
</widget>
<widget class="QPushButton" name="btnHide">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>92</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>隐藏托盘</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

31
other/trayicon/main.cpp Normal file
View File

@@ -0,0 +1,31 @@
#pragma execution_character_set("utf-8")
#include "frmtrayicon.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
frmTrayIcon w;
w.setWindowTitle("托盘图标");
w.show();
return a.exec();
}

BIN
other/trayicon/main.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

5
other/trayicon/main.qrc Normal file
View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>main.ico</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,98 @@
#pragma execution_character_set("utf-8")
#include "trayicon.h"
#include "qmutex.h"
#include "qmenu.h"
#include "qapplication.h"
#include "qdebug.h"
QScopedPointer<TrayIcon> TrayIcon::self;
TrayIcon *TrayIcon::Instance()
{
if (self.isNull()) {
static QMutex mutex;
QMutexLocker locker(&mutex);
if (self.isNull()) {
self.reset(new TrayIcon);
}
}
return self.data();
}
TrayIcon::TrayIcon(QObject *parent) : QObject(parent)
{
mainWidget = 0;
trayIcon = new QSystemTrayIcon(this);
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this, SLOT(iconIsActived(QSystemTrayIcon::ActivationReason)));
menu = new QMenu;
exitDirect = true;
}
void TrayIcon::iconIsActived(QSystemTrayIcon::ActivationReason reason)
{
switch (reason) {
case QSystemTrayIcon::Trigger:
case QSystemTrayIcon::DoubleClick: {
mainWidget->showNormal();
break;
}
default:
break;
}
}
bool TrayIcon::getVisible() const
{
return trayIcon->isVisible();
}
void TrayIcon::setExitDirect(bool exitDirect)
{
if (this->exitDirect != exitDirect) {
this->exitDirect = exitDirect;
}
}
void TrayIcon::setMainWidget(QWidget *mainWidget)
{
this->mainWidget = mainWidget;
menu->addAction("主界面", mainWidget, SLOT(showNormal()));
if (exitDirect) {
menu->addAction("退出", this, SLOT(closeAll()));
} else {
menu->addAction("退出", this, SIGNAL(trayIconExit()));
}
trayIcon->setContextMenu(menu);
}
void TrayIcon::showMessage(const QString &title, const QString &msg, QSystemTrayIcon::MessageIcon icon, int msecs)
{
trayIcon->showMessage(title, msg, icon, msecs);
}
void TrayIcon::setIcon(const QString &strIcon)
{
trayIcon->setIcon(QIcon(strIcon));
}
void TrayIcon::setToolTip(const QString &tip)
{
trayIcon->setToolTip(tip);
}
void TrayIcon::setVisible(bool visible)
{
trayIcon->setVisible(visible);
}
void TrayIcon::closeAll()
{
trayIcon->hide();
trayIcon->deleteLater();
qApp->exit();
}

66
other/trayicon/trayicon.h Normal file
View File

@@ -0,0 +1,66 @@
#ifndef TRAYICON_H
#define TRAYICON_H
/**
* 托盘图标控件 作者:feiyangqingyun(QQ:517216493) 2017-01-08
* 1. 可设置托盘图标对应所属主窗体。
* 2. 可设置托盘图标。
* 3. 可设置提示信息。
* 4. 自带右键菜单。
*/
#include <QObject>
#include <QSystemTrayIcon>
class QMenu;
#ifdef quc
class Q_DECL_EXPORT TrayIcon : public QObject
#else
class TrayIcon : public QObject
#endif
{
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:
bool getVisible() const;
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();
};
#endif // TRAYICON_H

View File

@@ -0,0 +1,19 @@
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
TARGET = trayicon
TEMPLATE = app
DESTDIR = $$PWD/../bin
CONFIG += warn_off
SOURCES += main.cpp
SOURCES += frmtrayicon.cpp
SOURCES += trayicon.cpp
HEADERS += frmtrayicon.h
HEADERS += trayicon.h
FORMS += frmtrayicon.ui
RESOURCES += main.qrc