无边框拖拽是参考Qt实战6.万能的无边框窗口(FramelessWindow) - Qt小罗 - 博客园的文章,对其代码进行修改而来。

使用的是qt6 所以有可能里面一些关于坐标的类需要修改一下类型

代码使用的话,我是直接让widget继承于framlessWidget,下图是效果图

相比较,我将m_movePoint变成是m_pressPoint距离鼠标的相对坐标;然后让m_bIsResizing的值由m_direction来判断是否要拉伸窗口,同时添加了一个透明的带边框的窗体border来实现预览移动而拉伸的状态,因为我将qt小罗的及时修改边框的位置和大小改成延时,所以需要有个能预览的边框来观看。

只要由鼠标按下和松开来调用其他函数,例如鼠标按下要对一些变量进行重新设置避免上次操作的影响、判断是否要拉伸窗口和让border绑定父窗口显示出border。其他函数需要自己查看

对于移动窗口的话,需要对派生类进行多几步的操作

列子:topWidget和mainWidgetLeft都是页面的边缘是我想在这些地方点击后能触发移动条件

void MainWidget::mousePressEvent(QMouseEvent* event)
{
int topWidgetHeight = this->topWidget->height();
int leftWidgetWidth = this->mainWidgetLeft->width(); int x = event->x();
int y = event->y();
// 以上获取的数据是分别是符合条件的区域和鼠标的相对坐标
// 判断是否符合窗口移动条件
if (x <= leftWidgetWidth || y <= topWidgetHeight) {
this->setMoveStatus(true);//true表示能够移动
} FramelessWidget::mousePressEvent(event);
}
//framelessWidget.h

#pragma once

#include <QWidget>
class TransparentBorder; class FramelessWidget : public QWidget
{
Q_OBJECT
public:
enum Direction {//鼠标处于哪个边界
BOTTOMRIGHT,
TOPRIGHT,
TOPLEFT,
BOTTOMLEFT,
RIGHT,
DOWN,
LEFT,
UP,
NONE
};
enum {//距离边界多少时改变鼠标样式
MARGIN_MIN_SIZE = 0,
MARGIN_MAX_SIZE = 4
};
public:
FramelessWidget(QWidget* parent = nullptr);
~FramelessWidget(); void setBorderColor(const QColor& color); protected:
bool event(QEvent* event) override;
void leaveEvent(QEvent* event) override;
void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
//修改鼠标样式,且是否处于边界
void updateRegion(QMouseEvent* event);
//修改大小和位置,即geometry
void resizeRegion(int marginTop, int marginBottom, int marginLeft, int marginRight);
void createShadow();
void maximizeWidget();
void minimizeWidget();
void restoreWidget(); void setMoveStatus(bool status); void paintEvent(QPaintEvent* event) override; private:
bool m_bIsPressed; //是否鼠标按下
bool m_bIsResizing; //是否要拉伸
bool m_bIsDoublePressed;//没用到
bool m_bIsMove;
QPoint m_pressPoint; //鼠标按下时的坐标
QPoint m_pressPoint_initial;//没用到
QPoint m_movePoint; //鼠标移动了的相对坐标
Direction m_direction; //鼠标的状态即在哪个边界 QRect rect; //用于存放geometry
TransparentBorder* border; }; class TransparentBorder :public QWidget {
public:
TransparentBorder();
~TransparentBorder(); void resizeBorder(const QPoint& movePoint,FramelessWidget::Direction direction);
void moveBorder(const QPoint& movePoint); void setParentRect(const QRect& rect);
void setBorderColor(const QColor& color);
protected: void paintEvent(QPaintEvent* event) override; private:
QPoint marginOrigin;
QRect parentRect;
QColor borderColor;
};

cpp文件

#include "framelesswidget.h"
#include <QEvent>
#include <QMouseEvent>
#include <QRect>
#include <QApplication>
#include <QGraphicsDropShadowEffect>
#include <QtMath>
#include <QPen>
#include <QPainter>
#include <QPainterPath>
#include "model/data.h" FramelessWidget::FramelessWidget(QWidget* parent)
: QWidget(parent), m_bIsPressed(false), m_bIsResizing(false), m_bIsDoublePressed(false),m_bIsMove(false),
m_direction(NONE)
{
setWindowFlags(Qt::FramelessWindowHint); //隐藏标题栏(无边框)
setAttribute(Qt::WA_StyledBackground); //启用样式背景绘制
//setAttribute(Qt::WA_TranslucentBackground); //背景透明
setAttribute(Qt::WA_Hover);
setAttribute(Qt::WA_StaticContents);
this->setMinimumSize(50, 50); border = new TransparentBorder();//并没有让border挂在this下面,所以得析构时得delete
border->hide(); } FramelessWidget::~FramelessWidget()
{
delete border;
} bool FramelessWidget::event(QEvent* event)
{
///
// 使得移除窗口仍能进行鼠标移动的事件
///
if (event->type() == QEvent::HoverMove) {
QHoverEvent* hoverEvent = static_cast<QHoverEvent*>(event);
QMouseEvent mouseEvent(QEvent::MouseMove, hoverEvent->pos(),
Qt::NoButton, Qt::NoButton, Qt::NoModifier);
mouseMoveEvent(&mouseEvent);
//LOG() << "hover move";
} return QWidget::event(event);
} void FramelessWidget::mousePressEvent(QMouseEvent* event)
{
QWidget::mousePressEvent(event);
if (event->button() == Qt::LeftButton) {
m_bIsPressed = true;
m_pressPoint = event->globalPos();//鼠标按下的绝对坐标
m_movePoint = QPoint(0, 0);//使得上次移动的相对坐标清零 }
//*
//如果m_direction不为NoNE 即 鼠标在窗口边界 那么就是要进行窗口拉伸
//*
if (m_direction != NONE) {
m_bIsResizing = true;
}
//由于使用的是 额外创建一个boder边框使得能够预览窗口的位置
// 所以得让boder知道要绑定谁,且知道他的geometry
if (m_bIsMove || m_bIsResizing) {
border->setParentRect(geometry());
border->show();//显示边框 }
} void FramelessWidget::mouseMoveEvent(QMouseEvent* event)
{ QWidget::mouseMoveEvent(event);
m_movePoint = event->globalPos() - m_pressPoint;
//LOG() <<"m_bIsResizing"<< m_bIsResizing;
//LOG() <<"m_bIsPressed"<< m_bIsPressed; //*
// 鼠标没按下 且 不处于拉伸状态才来判断是不是在边界
//*
if (windowState() != Qt::WindowMaximized && !m_bIsPressed && !m_bIsResizing) {
updateRegion(event);
} // LOG() << "width" << minimumWidth();
// LOG() << "height" << minimumHeight(); //*
// 鼠标按下 但不处于拉伸状态
//*
if (m_bIsPressed && !m_bIsResizing) {
border->moveBorder(m_movePoint);
}
//拉伸状态
else if (m_bIsResizing) {
border->resizeBorder(m_movePoint, m_direction);
} } // 用于识别是否是拉伸动作
void FramelessWidget::updateRegion(QMouseEvent* event)
{
QRect mainRect = geometry(); int marginTop = event->globalY() - mainRect.y();
int marginBottom = mainRect.y() + mainRect.height() - event->globalY();
int marginLeft = event->globalX() - mainRect.x();
int marginRight = mainRect.x() + mainRect.width() - event->globalX(); //LOG() << marginTop << "|" << marginBottom << "|" << marginLeft << "|" << marginRight; if (!m_bIsResizing && !m_bIsPressed) {
if ((marginRight >= MARGIN_MIN_SIZE && marginRight <= MARGIN_MAX_SIZE)
&& ((marginBottom <= MARGIN_MAX_SIZE) && marginBottom >= MARGIN_MIN_SIZE)) {
m_direction = BOTTOMRIGHT;
setCursor(Qt::SizeFDiagCursor);
}
else if ((marginTop >= MARGIN_MIN_SIZE && marginTop <= MARGIN_MAX_SIZE)
&& (marginRight >= MARGIN_MIN_SIZE && marginRight <= MARGIN_MAX_SIZE)) {
m_direction = TOPRIGHT;
setCursor(Qt::SizeBDiagCursor);
}
else if ((marginLeft >= MARGIN_MIN_SIZE && marginLeft <= MARGIN_MAX_SIZE)
&& (marginTop >= MARGIN_MIN_SIZE && marginTop <= MARGIN_MAX_SIZE)) {
m_direction = TOPLEFT;
setCursor(Qt::SizeFDiagCursor);
}
else if ((marginLeft >= MARGIN_MIN_SIZE && marginLeft <= MARGIN_MAX_SIZE)
&& (marginBottom >= MARGIN_MIN_SIZE && marginBottom <= MARGIN_MAX_SIZE)) {
m_direction = BOTTOMLEFT;
setCursor(Qt::SizeBDiagCursor);
}
else if (marginBottom <= MARGIN_MAX_SIZE && marginBottom >= MARGIN_MIN_SIZE) {
m_direction = DOWN;
setCursor(Qt::SizeVerCursor);
}
else if (marginLeft <= MARGIN_MAX_SIZE - 1 && marginLeft >= MARGIN_MIN_SIZE - 1) {
m_direction = LEFT;
setCursor(Qt::SizeHorCursor);
}
else if (marginRight <= MARGIN_MAX_SIZE && marginRight >= MARGIN_MIN_SIZE) {
m_direction = RIGHT;
setCursor(Qt::SizeHorCursor);
}
else if (marginTop <= MARGIN_MAX_SIZE && marginTop >= MARGIN_MIN_SIZE) {
m_direction = UP;
setCursor(Qt::SizeVerCursor);
}
else {
m_direction = NONE;
setCursor(Qt::ArrowCursor); }
}
//LOG() << m_direction; } //对窗口进行大小和位置进行设置
void FramelessWidget::resizeRegion(int marginTop, int marginBottom,
int marginLeft, int marginRight)
{
if (m_bIsPressed && m_bIsResizing) {
//LOG() << "resize" << m_direction;
switch (m_direction) {
case BOTTOMRIGHT:
{
rect = geometry();
rect.setBottomRight(rect.bottomRight() + m_movePoint);
this->setGeometry(rect);
}
break;
case TOPRIGHT:
{
rect = geometry();
// 设置的宽度 小于 最小宽度 高度 小于 最小高度
if (geometry().width() + m_movePoint.x() <= minimumWidth() && geometry().height() - m_movePoint.y() <= minimumHeight()) {
rect.setRect(rect.x() ,
rect.y() + rect.height() - minimumHeight(),
minimumWidth(),
minimumHeight());
//LOG() << "1";
}
// 设置的宽度 小于 最小宽度 高度 大于 最小高度
else if (geometry().width() + m_movePoint.x() <= minimumWidth() && geometry().height() - m_movePoint.y() > minimumHeight()) {
rect.setRect(rect.x() ,
rect.y() + m_movePoint.y(),
minimumWidth(),
rect.height() - m_movePoint.y());
//LOG() << "2";
}
// 设置的宽度 大于 最小宽度 高度 小于 最小高度
else if (geometry().height() - m_movePoint.y() <= minimumHeight() && geometry().width() + m_movePoint.x() > minimumWidth()) {
rect.setRect(rect.x() ,
rect.y() + rect.height() - minimumHeight(),
rect.width() + m_movePoint.x(),
minimumHeight());
//LOG() << "3"<<rect; }
// 设置的宽度 大于 最小宽度 高度 大于 最小高度
else {
rect.setTopRight(rect.topRight() + m_movePoint);
//LOG() << "4"; } this->setGeometry(rect);
}
break;
case TOPLEFT:
{
rect = geometry();
// 设置的宽度 小于 最小宽度 高度 小于 最小高度
if (geometry().width() - m_movePoint.x() <= minimumWidth() && geometry().height() - m_movePoint.y() <= minimumHeight()) {
rect.setRect(rect.x() +rect.width() -minimumWidth(),
rect.y() + rect.height() -minimumHeight(),
minimumWidth(),
minimumHeight());
//LOG() << "1";
}
// 设置的宽度 小于 最小宽度 高度 大于 最小高度
else if (geometry().width() - m_movePoint.x() <= minimumWidth() && geometry().height() - m_movePoint.y() > minimumHeight()) {
rect.setRect(rect.x() +rect.width() -minimumWidth() ,
rect.y() + m_movePoint.y(),
minimumWidth(),
rect.height() - m_movePoint.y());
//LOG() << "2";
}
// 设置的宽度 大于 最小宽度 高度 小于 最小高度
else if (geometry().height() - m_movePoint.y() <= minimumHeight() && geometry().width() - m_movePoint.x() > minimumWidth()) {
rect.setRect(rect.x() + m_movePoint.x(),
rect.y() + rect.height() - minimumHeight(),
rect.width() - m_movePoint.x(),
minimumHeight());
//LOG() << "3"<<rect; }
// 设置的宽度 大于 最小宽度 高度 大于 最小高度
else {
rect.setTopLeft(rect.topLeft() + m_movePoint);
//LOG() << "4"; } this->setGeometry(rect); }
break;
case BOTTOMLEFT:
{
rect = geometry();
// 设置的宽度 小于 最小宽度 高度 小于 最小高度
if (geometry().width() - m_movePoint.x() <= minimumWidth() && geometry().height() + m_movePoint.y() <= minimumHeight()) {
rect.setRect(rect.x() +rect.width() -minimumWidth(),
rect.y(),
minimumWidth(),
minimumHeight());
//LOG() << "1";
}
// 设置的宽度 小于 最小宽度 高度 大于 最小高度
else if (geometry().width() - m_movePoint.x() <= minimumWidth() && geometry().height() + m_movePoint.y() > minimumHeight()) {
rect.setRect(rect.x() +rect.width() -minimumWidth() ,
rect.y(),
minimumWidth(),
rect.height() + m_movePoint.y());
//LOG() << "2";
}
// 设置的宽度 大于 最小宽度 高度 小于 最小高度
else if (geometry().height() + m_movePoint.y() <= minimumHeight() && geometry().width() - m_movePoint.x() > minimumWidth()) {
rect.setRect(rect.x() + m_movePoint.x(),
rect.y(),
rect.width() - m_movePoint.x(),
minimumHeight());
//LOG() << "3"<<rect; }
// 设置的宽度 大于 最小宽度 高度 大于 最小高度
else {
rect.setBottomLeft(rect.bottomLeft() + m_movePoint);
//LOG() << "4"; } this->setGeometry(rect); }
break;
case RIGHT:
{
rect = geometry();
rect.setRight(rect.right() + m_movePoint.x());
this->setGeometry(rect);
//setFixedSize(rect.width(), rect.height()); }
break;
case DOWN:
{
rect = geometry();
rect.setBottom(rect.bottom() + m_movePoint.y());
//rect.setHeight(rect.height() + m_movePoint.y());
this->setGeometry(rect);
//setFixedSize(rect.width(), rect.height());
//LOG() << "down";
}
break;
case LEFT:
{
if (geometry().width() - m_movePoint.x() < minimumWidth()) {
rect = geometry();
rect.setRect(rect.x() + rect.width() - minimumWidth(),
rect.y() ,
minimumWidth(),
rect.height());
this->setGeometry(rect);
}
else { rect = geometry();
rect.setLeft(rect.left() + m_movePoint.x());
//rect.setX(rect.width() - m_movePoint.x());
this->setGeometry(rect); //setFixedSize(rect.width(), rect.height());
//this->move(rect.x() + m_movePoint.x(), rect.y());
}
}
break;
case UP:
{
if (geometry().height() - m_movePoint.y() < minimumHeight()) {
rect = geometry();
rect.setRect(rect.x(),
rect.y() + rect.height() - minimumHeight(),
rect.width(),
minimumHeight());
this->setGeometry(rect);
}
else {
rect = geometry();
rect.setTop(rect.top() + m_movePoint.y());
this->setGeometry(rect);
//LOG() << "UP";
} }
break;
default:
{
}
break;
}
}
else {
m_bIsResizing = false;
//当不在边界一定得设置NONE,不然会导致在边界后,下次不在边界会被判断成拉伸状态
m_direction = NONE;
}
} void FramelessWidget::mouseReleaseEvent(QMouseEvent* event)
{
///
// 鼠标松开 需要判断 是否处于拉伸状态需要修改窗口
// 是否是窗口需要移动
///
QWidget::mouseReleaseEvent(event);
//LOG() << m_direction;
if (NONE != m_direction) {
//LOG() << "resize";
resizeRegion(0, 0, 0, 0);
}
// 鼠标松开,当鼠标按下的状态还没修改
// 处于移动窗口的状态
if (!m_bIsResizing && m_bIsPressed && m_bIsMove) {
this->move(geometry().x() + m_movePoint.x(), geometry().y() + m_movePoint.y());
}
this->setMoveStatus(false);
//LOG() << "1:" << geometry(); // 修改鼠标的样式
if (windowState() != Qt::WindowMaximized) {
updateRegion(event);
} //重置值,防止影响下次判断
if (event->button() == Qt::LeftButton) {
m_bIsPressed = false;
m_bIsResizing = false;
m_bIsDoublePressed = false;
m_direction = NONE;
}
//完成 操作 取消显示边框
border->hide(); //LOG() << "move_point" << m_movePoint;
//LOG()<<"2:" << geometry();
} void FramelessWidget::leaveEvent(QEvent *event)
{
// m_bIsPressed = false;
// m_bIsDoublePressed = false;
// m_bIsResizing = false; QWidget::leaveEvent(event);
} void FramelessWidget::createShadow()
{
QGraphicsDropShadowEffect *shadowEffect = new QGraphicsDropShadowEffect(this);
shadowEffect->setColor(Qt::black);
shadowEffect->setOffset(0, 0);
shadowEffect->setBlurRadius(13);
this->setGraphicsEffect(shadowEffect);
} void FramelessWidget::maximizeWidget()
{ showMaximized();
}
void FramelessWidget::minimizeWidget()
{
showMinimized();
}
void FramelessWidget::restoreWidget()
{ showNormal();
} void FramelessWidget::setMoveStatus(bool status)
{
this->m_bIsMove = status;
} void FramelessWidget::setBorderColor(const QColor& color)
{
this->border->setBorderColor(color);
} void FramelessWidget::paintEvent(QPaintEvent* event)
{ QWidget::paintEvent(event); } TransparentBorder::TransparentBorder():
QWidget(),marginOrigin(0,0),parentRect(0,0,0,0),borderColor(Qt::white)
{
setWindowOpacity(1);
this->setAttribute(Qt::WA_TranslucentBackground, true);//透明
this->setWindowFlags(Qt::FramelessWindowHint);//无边框 } TransparentBorder::~TransparentBorder()
{
} //边框的大小设置
void TransparentBorder::resizeBorder(const QPoint& m_movePoint, FramelessWidget::Direction direction)
{
switch (direction) {
case FramelessWidget::Direction::BOTTOMRIGHT:
{
LOG() << "BottomRight";
QRect rect(parentRect);
rect.setBottomRight(rect.bottomRight() + m_movePoint);
this->setGeometry(rect);
}
break;
case FramelessWidget::Direction::TOPRIGHT:
{
QRect rect(parentRect);
rect.setTopRight(rect.topRight() + m_movePoint);
this->setGeometry(rect);
}
break;
case FramelessWidget::Direction::TOPLEFT:
{
QRect rect(parentRect);
rect.setTopLeft(rect.topLeft() + m_movePoint);
this->setGeometry(rect);
}
break;
case FramelessWidget::Direction::BOTTOMLEFT:
{
QRect rect(parentRect);
rect.setBottomLeft(rect.bottomLeft() + m_movePoint);
this->setGeometry(rect);
}
break;
case FramelessWidget::Direction::RIGHT:
{
QRect rect(parentRect);
rect.setRight(rect.right() + m_movePoint.x());
setGeometry(rect); }
break;
case FramelessWidget::Direction::DOWN:
{
//LOG() << "down";
//LOG() << "parentRect:" << parentRect;
QRect rect(parentRect);
rect.setBottom(rect.bottom() + m_movePoint.y());
//rect.setHeight(rect.height() + m_movePoint.y());
setGeometry(rect); }
break;
case FramelessWidget::Direction::LEFT:
{
QRect rect(parentRect);
rect.setLeft(rect.left() + m_movePoint.x());
setGeometry(rect); }
break;
case FramelessWidget::Direction::UP:
{
QRect rect(parentRect);
//rect.setHeight(rect.height() - m_movePoint.y());
rect.setTop(rect.top() + m_movePoint.y());
setGeometry(rect);
//setFixedSize(rect.width(), rect.height());
//LOG() << "UP"; }
break;
default:
{
}
break;
} } //移动边框
void TransparentBorder::moveBorder(const QPoint& movePoint)
{
this->move(parentRect.x()+movePoint.x(), parentRect.y()+movePoint.y());
} //设置要绑定哪个窗口
void TransparentBorder::setParentRect(const QRect& rect)
{
parentRect.setRect(rect.x(),rect.y(),rect.width(),rect.height());
this->setGeometry(parentRect); } void TransparentBorder::setBorderColor(const QColor& color)
{
borderColor = color;
} // 渲染时画出出边框
void TransparentBorder::paintEvent(QPaintEvent *event)
{ QRect rect = geometry();
QPainter painter(this);
painter.setBrush(QColor(9,151,247,1));//painter区域全部的背景色
painter.setPen(QPen(borderColor,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
painter.setCompositionMode(QPainter::CompositionMode_Difference);
painter.drawRect(0,0,rect.width(),rect.height()); //this->resize(parentRect.width(),parentRect.height());
}

实现qt 窗口无边框拖拽的更多相关文章

  1. Qt 无边框拖拽实现

    Qt 无边框拖拽实现 头文件定义: class TDragProxy:public QObject { Q_OBJECT public: TDragProxy(QWidget* parent); ~T ...

  2. QT窗口无边框最前

    this->setWindowFlags(Qt::WindowStaysOnTopHint| Qt::CustomizeWindowHint| Qt::Tool| Qt::FramelessWi ...

  3. Qt——透明无边框Widget的bug

    Experience 最近在封装一些类的时候,打算做一个窗口框架,能实现拖动.缩放.最大最小化.基本样式等功能,可不慎遇见一件无比蛋疼的事情,QWidget最小化后再恢复正常界面,最小化按钮居然仍处于 ...

  4. HTML5 CSS3 经典案例:无插件拖拽上传图片 (支持预览与批量) (二)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/31513065 上一篇已经实现了这个项目的整体的HTML和CSS: HTML5 C ...

  5. 让Qt的无边框窗口支持拖拽、Aero Snap、窗口阴影等特性

    环境:Desktop Qt 5.4.1 MSVC2013 32bit 需要的库:dwmapi.lib .user32.lib 需要头文件:<dwmapi.h> .<windowsx. ...

  6. Qt5.3中qml ApplicationWindow设置窗口无边框问题

    这个版本的qt在这里有点bug.. 设置ApplicationWindow的flags属性为Qt.FramelessWindowHint的确可以使程序无边框,但是同时程序在任务栏的图标也没了. 看文档 ...

  7. 2017年11月20日 WinForm窗体 窗口无边框可移动&&窗口阴影 控制窗口关闭/最小化

    弹框 MessageBox.Show(); 清空 clear() 字符串拼接 string 公共控件 button 按钮 checkbox 复选框 checklistbox 多个复选框 combobo ...

  8. C# 实现窗口无边框,可拖动效果

    #region 无边框拖动效果 [DllImport("user32.dll")]//拖动无窗体的控件 public static extern bool ReleaseCaptu ...

  9. C# WinForm设置窗口无边框、窗口可移动、窗口显示在屏幕中央、控件去边框

    1)窗口去除边框 在组件属性中FormBorderStyle设为None 2)窗口随着鼠标移动而动 添加引用using System.Runtime.InteropServices; 在初始化控件{I ...

  10. Qt学习-ListView的拖拽

    最近在学习Qt 里面的QML, 使用DropArea和MouseArea实现了ListView的拖拽. 想起了当年用Delphi, 差不多一样的东西, 不过那是2000了. Delphi也是不争气啊, ...

随机推荐

  1. FastAPI Cookie 和 Header 参数完全指南:从基础到高级实战 🚀

    title: FastAPI Cookie 和 Header 参数完全指南:从基础到高级实战 date: 2025/3/9 updated: 2025/3/9 author: cmdragon exc ...

  2. python 二级 函数与代码复用

  3. k8s 手动更新 seldon core ca证书

    前言 seldon core 报错:x509: certificate has expired or is not yet valid: current time 这是因为 seldon core 默 ...

  4. TidHTTP的post编码,老掉牙的问题

    TidHTTP使用post时,需要提交json字符串. 那么采用什么编码,这个问题就头大了.目前xe已经不要考虑编码转换问题.但是.... 我们使用ISuperObject操控json.那么最后提交到 ...

  5. 工具推荐-根据IP地址精确定位经纬度(永久免费)

    今天小张由于业务需求,需要根据用户的访问ip精确定位用户的国家.城市.及经纬度等信息,从网上进行搜索,发现不少的网站,但几乎没有完全符合的,有个别符合的还需要花钱,大家也知道,现在是信息共享的时代,难 ...

  6. RAGflow搭建text-to-sql的AI研发助手

    一.概述 text-to-sql 技术允许用户通过自然语言提问,系统自动将其转换为 SQL 语句并执行,大大降低了数据查询的门槛,提高了工作效率. text-to-sql 技术在数据分析.智能客服.数 ...

  7. Greenplum常用命令、函数

    Greenplum常用查询命令 #查看test_bd事务(即数据库)下的所有表名包含 user 的 表信息 SELECT UPPER(A.SCHEMANAME) AS SCHEMANAME, UPPE ...

  8. CSP - J理论(1)

    CSP-J理论(1) CSP-J理论合集跳转 目录 本目录中所有标题单击均可以快速跳转哦 一.排列组合与概率 $\ \ \ \ \ $1.排列 $\ \ \ \ \ $2.组合 $\ \ \ \ \ ...

  9. Mybatis的原始的执行方式

    一.通过SqlSessionFactory创建sqlsession,再由Sqlsession获取session对象,然后通过session中的执行器Executor,去执行MapperStatemen ...

  10. kettle介绍-Step之Write to log

    Write to log写日志介绍 写日志步骤是将输入步骤的信息打印在日志窗口,供用户直接查看 Step name:步骤的名称,在单一转换中,名称必须唯一. Log level:设置日志的显示级别. ...