更新滑动开关

This commit is contained in:
JackLee 2025-03-05 16:03:21 +08:00
parent 5d4f0b9740
commit 38db6b9587
10 changed files with 234 additions and 283 deletions

View File

@ -28,9 +28,10 @@ QPushButton#btn_user_switch_knowledge,
QPushButton#btn_user_upload_file,
QPushButton#btn_user_clear_context,
QPushButton#btn_user_sending_info{
width:25px;
height:25px;
width:30px;
height:30px;
border:none;
margin:5px;
}
QComboBox{
height:25px;

View File

@ -7,7 +7,6 @@ ctai_history_textedit::ctai_history_textedit(QWidget *parent)
}
ctai_history_textedit::~ctai_history_textedit()
{
}
void ctai_history_textedit::init_layout(msg_type msg_type_mode)
{
@ -33,8 +32,8 @@ void ctai_history_textedit::init_layout(msg_type msg_type_mode)
m_history_to_send = new QPushButton();
m_msg_system_del = new QPushButton();
m_restart_to_send = new QPushButton();
m_msg_tokens->setObjectName("m_msg_tokens");
m_history_to_send->setObjectName("m_history_to_send");
m_msg_tokens->setObjectName("m_msg_tokens");
m_history_to_send->setObjectName("m_history_to_send");
m_msg_system_del->setObjectName("m_msg_system_del");
m_restart_to_send->setObjectName("m_restart_to_send");
header_info_Layout->addWidget(m_history_to_send);
@ -43,19 +42,19 @@ void ctai_history_textedit::init_layout(msg_type msg_type_mode)
header_info_Layout->addWidget(m_msg_system_del);
// 3.消息功能区
header_opts_Layout = new QHBoxLayout();
header_opts_Layout = new QHBoxLayout();
m_msg_copy = new QPushButton();
m_msg_save = new QPushButton();
m_msg_menu = new QPushButton();
m_msg_fold = new QPushButton();
m_msg_copy->setObjectName("m_msg_copy");
m_msg_save->setObjectName("m_msg_save");
m_msg_menu->setObjectName("m_msg_menu");
m_msg_fold->setObjectName("m_msg_fold");
m_msg_fold->setIcon(QIcon(":res/img/btn/btn_info_up.png"));
m_msg_fold->setMinimumSize(QSize(25, 25));
header_opts_Layout->addItem(sparcer_item);
header_opts_Layout->addItem(sparcer_item);
header_opts_Layout->addWidget(m_msg_copy);
header_opts_Layout->addWidget(m_msg_save);
header_opts_Layout->addWidget(m_msg_menu);
@ -79,7 +78,7 @@ void ctai_history_textedit::init_layout(msg_type msg_type_mode)
m_history_to_send = new QPushButton();
m_history_to_send->setObjectName("m_history_to_send");
m_restart_to_send = new QPushButton();
m_restart_to_send->setObjectName("m_restart_to_send");
m_restart_to_send->setObjectName("m_restart_to_send");
header_info_Layout->addWidget(m_history_to_send);
header_info_Layout->addWidget(m_restart_to_send);
header_info_Layout->addWidget(m_msg_user_del);
@ -309,7 +308,7 @@ void ctai_history_textedit::add_header_message(const model_data &message)
void ctai_history_textedit::on_delete_clicked()
{
// 发送删除请求信号
emit delete_requested(m_msg_sned_id);
emit delete_requested(m_msg_sned_id);
}
void ctai_history_textedit::on_copy_clicked()

View File

@ -27,7 +27,6 @@
// 系统相关
#include <mutex>
// 项目相关头文件
#include "ctai_base.h"
#include "ctai_markdown.h"

View File

@ -133,59 +133,31 @@ void ctai_history_widget::on_rows_height_changed(bool fold_state)
void ctai_history_widget::on_msg_remove(QString send_id)
{
// 添加更多调试信息
qDebug() << "Removing message with send_id:" << send_id;
qDebug() << "Current row count:" << rowCount();
qDebug()<<"send_id:"<<send_id;
auto it = message_map_.find(send_id);
if (it != message_map_.end())
{
int row_to_remove = it->second.second;
qDebug() << "it row count:" << it->second.second;
// 验证行号是否有效
if (row_to_remove < 0 || row_to_remove >= rowCount())
{
qDebug() << "Invalid row index:" << row_to_remove;
return;
}
// 1. 先处理cell widget
QWidget *widget = cellWidget(row_to_remove, 0);
if (widget)
{
// 断开该widget的所有信号连接
widget->disconnect();
// 从表格中移除widget
removeCellWidget(row_to_remove, 0);
// 标记widget待删除
widget->deleteLater();
}
// 2. 删除model数据
if (it->second.first)
{
delete it->second.first;
it->second.first = nullptr;
}
// 3. 从map中移除
// 获取要删除的行号
int row_to_remove = it->second.second-1;
qDebug()<<"row_to_remove:"<<row_to_remove;
// 删除model_data
delete it->second.first;
// 从map中移除该元素
message_map_.erase(it);
// 4. 最后删除行
blockSignals(true); // 暂时阻止信号
// 从表格中移除该行
removeRow(row_to_remove);
blockSignals(false); // 恢复信号
// 5. 更新其他行的索引
for (auto &pair : message_map_)
// 更新map中所有大于被删除行号的行号
for (auto& pair : message_map_)
{
if (pair.second.second > row_to_remove)
{
// 更新行号
pair.second.second--;
}
}
qDebug() << "Row removed successfully. New row count:" << rowCount();
}
}

View File

@ -53,8 +53,11 @@ void ctai_session_info::init_sub_layout()
m_session_user_edit_layout->addWidget(m_session_user_edit_info);
m_session_user_btn_layout = new QHBoxLayout();
m_stream_switch = new ctai_switch_control();
m_stream_mode_tips = new QLabel();
m_stream_switch = new ctai_switch_button();
m_stream_switch->setSwBtn_Status(true);
ctai_session_set_steam_mode(true);
m_stream_switch->setMinimumSize(QSize(75, 25));
m_stream_mode_tips = new QLabel(tr("流式模式:"));
m_info_error_tips = new QLabel();
init_user_btn_layout();
m_session_user_group_layout->addLayout(m_session_user_edit_layout);
@ -78,7 +81,7 @@ void ctai_session_info::init_user_btn_layout()
m_session_user_btn_layout->addItem(sparcer_item);
m_session_user_btn_layout->addWidget(m_stream_mode_tips);
m_session_user_btn_layout->addWidget(m_stream_switch);
connect(m_stream_switch, SIGNAL(toggled(bool)), this, SLOT(ctai_session_set_steam_mode(bool)));
connect(m_stream_switch, SIGNAL(SwBtn_SWITCH(bool)), this, SLOT(ctai_session_set_steam_mode(bool)));
}
m_session_user_btn_layout->addWidget(btn);
switch (i)
@ -147,9 +150,8 @@ void ctai_session_info::ctai_session_curl_state_tips(std::string state_str)
}
void ctai_session_info::ctai_session_set_steam_mode(bool state)
{
m_stream_mode!=state;
qDebug() << "steam mode:" << state;
m_stream_switch->setToggle(state);
m_stream_mode=state;
}
void ctai_session_info::ctai_session_user_sending()
{

View File

@ -10,7 +10,7 @@
#include <QListWidget>
#include <QDir>
#include <QFile>
#include "ctai_switch_control.h"
#include "ctai_switch_button.h"
#include "ctai_curl.h"
#include "ctai_history_widget.h"
class ctai_session_info : public QWidget
@ -43,7 +43,7 @@ private:
std::vector<QPushButton *> m_btns;
QLabel *m_stream_mode_tips;
QLabel *m_info_error_tips;
ctai_switch_control *m_stream_switch;
ctai_switch_button *m_stream_switch;
QHBoxLayout *m_session_user_btn_layout;
QVBoxLayout *m_session_user_group_layout;

155
src/ctai_switch_button.cpp Normal file
View File

@ -0,0 +1,155 @@
#include "ctai_switch_button.h"
ctai_switch_button::ctai_switch_button(QWidget *parent)
: QWidget(parent),
m_SwBtn_Status(false),
m_SwBtn_background(Qt::black),
//m_SwBtn_checkedColor(0,150,136),
m_SwBtn_checkedColor(255,000,000),
m_SwBtn_disabilityColor(190,190,190),
m_SwBtn_thumbColor(Qt::white),
m_SwBtn_radius(5),
m_SwBtn_Height(10),
m_SwBtn_Margin(10)
{
setCursor(Qt::PointingHandCursor);
connect(&m_SwBtn_timer,SIGNAL(timeout()),this,SLOT(SwBtn_Slide()));
}
bool ctai_switch_button::SwBtn_isChecked() const
{
return m_SwBtn_Status;
}
void ctai_switch_button::setSwBtn_Status(bool check)
{
m_SwBtn_Status=check;
m_SwBtn_timer.start(10);
}
void ctai_switch_button::setSwBtn_BackgroundColor(QColor color)
{
m_SwBtn_background=color;
}
void ctai_switch_button::setSwBtn_CheckedColor(QColor color)
{
m_SwBtn_checkedColor=color;
}
void ctai_switch_button::setSwBtn_DisabilityColor(QColor color)
{
m_SwBtn_disabilityColor=color;
}
void ctai_switch_button::setSwBtn_WidgetSize(int m_width, int m_height)
{
this->m_SwBtn_Height=m_width-m_height;
this->m_SwBtn_Margin=m_height-(m_width/2);
this->m_SwBtn_radius=m_SwBtn_Height/2;
update();
}
void ctai_switch_button::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
QColor background;
QColor thumbColor;
qreal pellucidity;
if(isEnabled()){
if(m_SwBtn_Status){
background=m_SwBtn_checkedColor;
thumbColor=m_SwBtn_checkedColor;
pellucidity=0.6;
}
else{
background=m_SwBtn_background;
thumbColor=m_SwBtn_thumbColor;
pellucidity=0.8;
}
}
else{
background=m_SwBtn_background;
thumbColor=m_SwBtn_disabilityColor;
pellucidity=0.2;
}
painter.setBrush(background);
painter.setOpacity(pellucidity);
path.addRoundedRect(QRectF(m_SwBtn_Margin,
m_SwBtn_Margin,
width()-2*m_SwBtn_Margin,
height()-2*m_SwBtn_Margin),
m_SwBtn_radius,
m_SwBtn_radius);
painter.drawPath(path.simplified());
painter.setBrush(thumbColor);
painter.setOpacity(1);
painter.drawEllipse(QRectF(m_SwBtn_X/*-(m_SwBtn_Height/2)*/,
m_SwBtn_Y+5/*-(m_SwBtn_Height/2)*/,
height()-10,
height()-10));
}
void ctai_switch_button::mousePressEvent(QMouseEvent *event)
{
if(isEnabled()){
if(event->button()==Qt::LeftButton){ //**
event->accept();
}
else
event->ignore();
}
}
void ctai_switch_button::mouseReleaseEvent(QMouseEvent *event)
{
if(isEnabled()){
if((event->type()==QMouseEvent::MouseButtonRelease)&&(event->button()==Qt::LeftButton)){
event->accept();
m_SwBtn_Status=!m_SwBtn_Status;
emit SwBtn_SWITCH(m_SwBtn_Status);
m_SwBtn_timer.start(10);
}
else{
event->ignore();
}
}
}
//重现大小改变事件
void ctai_switch_button::resizeEvent(QResizeEvent *event)
{
m_SwBtn_X=0;
m_SwBtn_Y=0;
QWidget::resizeEvent(event);
}
QSize ctai_switch_button::sizeHint() const
{
return minimumSizeHint();
}
QSize ctai_switch_button::minimumSizeHint() const
{
return QSize(2*(m_SwBtn_Height+m_SwBtn_Margin),m_SwBtn_Height+2*m_SwBtn_Margin);
}
void ctai_switch_button::SwBtn_Slide()
{
if(m_SwBtn_Status){
m_SwBtn_X+=1;
if(m_SwBtn_X>=width()-height())
m_SwBtn_timer.stop();
}
else{
m_SwBtn_X-=1;
if(m_SwBtn_X<=0)
m_SwBtn_timer.stop();
}
update();
}

46
src/ctai_switch_button.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef CTAI_SWITCH_BUTTON_H
#define CTAI_SWITCH_BUTTON_H
#include <QWidget>
#include <QTimer>
#include <QPainter>
#include <QMouseEvent>
#include <QPainterPath>
class ctai_switch_button : public QWidget
{
Q_OBJECT
public:
explicit ctai_switch_button(QWidget *parent = nullptr);
bool SwBtn_isChecked() const;
void setSwBtn_Status(bool check);
void setSwBtn_BackgroundColor(QColor color);
void setSwBtn_CheckedColor(QColor color);
void setSwBtn_DisabilityColor(QColor color);
void setSwBtn_WidgetSize(int m_width,int m_height);
protected:
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
QSize sizeHint() const Q_DECL_OVERRIDE;
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
signals:
void SwBtn_SWITCH(bool check);
private slots:
void SwBtn_Slide();
private:
bool m_SwBtn_Status;
QColor m_SwBtn_background;
QColor m_SwBtn_checkedColor;
QColor m_SwBtn_disabilityColor;
QColor m_SwBtn_thumbColor;
qreal m_SwBtn_radius;
qreal m_SwBtn_X;
qreal m_SwBtn_Y;
qint16 m_SwBtn_Height;
qint16 m_SwBtn_Margin;
QTimer m_SwBtn_timer;
};
#endif // SWITCH_CONTROL

View File

@ -1,152 +0,0 @@
#include "ctai_switch_control.h"
ctai_switch_control::ctai_switch_control(QWidget *parent)
: QWidget(parent),
m_nHeight(16),
m_bChecked(false),
m_radius(8.0),
m_nMargin(3),
m_checkedColor(0, 150, 136),
m_thumbColor(Qt::white),
m_disabledColor(190, 190, 190),
m_background(Qt::black)
{
// 鼠标滑过光标形状 - 手型
setCursor(Qt::PointingHandCursor);
// 连接信号槽
connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}
// 绘制开关
void ctai_switch_control::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
QPainterPath path;
QColor background;
QColor thumbColor;
qreal dOpacity;
if (isEnabled()) { // 可用状态
if (m_bChecked) { // 打开状态
background = m_checkedColor;
thumbColor = m_checkedColor;
dOpacity = 0.600;
} else { //关闭状态
background = m_background;
thumbColor = m_thumbColor;
dOpacity = 0.800;
}
} else { // 不可用状态
background = m_background;
dOpacity = 0.260;
thumbColor = m_disabledColor;
}
// 绘制大椭圆
painter.setBrush(background);
painter.setOpacity(dOpacity);
path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin, height() - 2 * m_nMargin), m_radius, m_radius);
painter.drawPath(path.simplified());
// 绘制小椭圆
painter.setBrush(thumbColor);
painter.setOpacity(1.0);
painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height()));
}
// 鼠标按下事件
void ctai_switch_control::mousePressEvent(QMouseEvent *event)
{
if (isEnabled()) {
if (event->buttons() & Qt::LeftButton) {
event->accept();
} else {
event->ignore();
}
}
}
// 鼠标释放事件 - 切换开关状态、发射toggled()信号
void ctai_switch_control::mouseReleaseEvent(QMouseEvent *event)
{
if (isEnabled()) {
if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) {
event->accept();
m_bChecked = !m_bChecked;
emit toggled(m_bChecked);
m_timer.start(10);
} else {
event->ignore();
}
}
}
// 大小改变事件
void ctai_switch_control::resizeEvent(QResizeEvent *event)
{
m_nX = m_nHeight / 2;
m_nY = m_nHeight / 2;
QWidget::resizeEvent(event);
}
// 默认大小
QSize ctai_switch_control::sizeHint() const
{
return minimumSizeHint();
}
// 最小大小
QSize ctai_switch_control::minimumSizeHint() const
{
return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin);
}
// 切换状态 - 滑动
void ctai_switch_control::onTimeout()
{
if (m_bChecked) {
m_nX += 1;
if (m_nX >= width() - m_nHeight)
m_timer.stop();
} else {
m_nX -= 1;
if (m_nX <= m_nHeight / 2)
m_timer.stop();
}
update();
}
// 返回开关状态 - 打开true 关闭false
bool ctai_switch_control::isToggled() const
{
return m_bChecked;
}
// 设置开关状态
void ctai_switch_control::setToggle(bool checked)
{
m_bChecked = checked;
m_timer.start(10);
}
// 设置背景颜色
void ctai_switch_control::setBackgroundColor(QColor color)
{
m_background = color;
}
// 设置选中颜色
void ctai_switch_control::setCheckedColor(QColor color)
{
m_checkedColor = color;
}
// 设置不可用颜色
void ctai_switch_control::setDisbaledColor(QColor color)
{
m_disabledColor = color;
}

View File

@ -1,71 +0,0 @@
#ifndef CTAI_SWITCH_CONTROL_H
#define CTAI_SWITCH_CONTROL_H
#include <QWidget>
#include <QTimer>
#include <QPainter>
#include <QMouseEvent>
#include <QPainterPath>
class ctai_switch_control : public QWidget
{
Q_OBJECT
public:
explicit ctai_switch_control(QWidget *parent = 0);
// 返回开关状态 - 打开true 关闭false
bool isToggled() const;
// 设置开关状态
void setToggle(bool checked);
// 设置背景颜色
void setBackgroundColor(QColor color);
// 设置选中颜色
void setCheckedColor(QColor color);
// 设置不可用颜色
void setDisbaledColor(QColor color);
protected:
// 绘制开关
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
// 鼠标按下事件
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
// 鼠标释放事件 - 切换开关状态、发射toggled()信号
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
// 大小改变事件
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
// 缺省大小
QSize sizeHint() const Q_DECL_OVERRIDE;
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
signals:
// 状态改变时,发射信号
void toggled(bool checked);
private slots:
// 状态切换时,用于产生滑动效果
void onTimeout();
private:
bool m_bChecked; // 是否选中
QColor m_background; // 背景颜色
QColor m_checkedColor; // 选中颜色
QColor m_disabledColor; // 不可用颜色
QColor m_thumbColor; // 拇指颜色
qreal m_radius; // 圆角
qreal m_nX; // x点坐标
qreal m_nY; // y点坐标
qint16 m_nHeight; // 高度
qint16 m_nMargin; // 外边距
QTimer m_timer; // 定时器
};
#endif // SWITCH_CONTROL