wumu
2025-10-30 5f8a4c8d12855caa8d06cfcc5caa5a0601563710
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#include "positionmanagement.h"
#include "ui_positionmanagement.h"
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QComboBox>
#include <QDebug>
#include <QMessageBox>
#include <QDateTime>
#include <QMessageBox>
 
PositionManagement::PositionManagement(QWidget *parent):
    QMainWindow(parent),
    ui(new Ui::PositionManagement)
{
    ui->setupUi(this);
 
    m_modelAll = new QStandardItemModel(this);
    m_modelShort = new QStandardItemModel(this);
    m_modelMid = new QStandardItemModel(this);
    m_modelLong = new QStandardItemModel(this);
 
    QStringList labels; // 14列
    labels<<"id"<<"股票"<<"code"<<"入池时间"<<"入池价格"<<"购买时间"<<"购买价格"
         <<"卖出时间"<<"卖出价格"<<"入池收益"<<"买入收益"<<"卖出收益"<<"类型"<<"状态"<<"当前价格";
 
    m_modelAll->setHorizontalHeaderLabels(labels);
    m_modelShort->setHorizontalHeaderLabels(labels);
    m_modelMid->setHorizontalHeaderLabels(labels);
    m_modelLong->setHorizontalHeaderLabels(labels);
 
    ui->tableView_all->setModel(m_modelAll);
    ui->tableView_short->setModel(m_modelShort);
    ui->tableView_mid->setModel(m_modelMid);
    ui->tableView_long->setModel(m_modelLong);
 
    // 初始化数据库
    initMySQL();
 
    // 添加股票信息相关
    m_addDlg = new QDialog(this);
    m_addDlg->setWindowTitle("添加股票到仓位池");
    QVBoxLayout *vb = new QVBoxLayout(m_addDlg);
    QStringList placetext;
    placetext<<"输入股票名字"<<"输入股票代号"<<"输入价格";
    for(int i=0;i<3;++i){
        QLineEdit *lt = new QLineEdit(this);
        lt->setPlaceholderText(placetext.at(i));
        vb->addWidget(lt);
        m_lineEdits.append(lt);
    }
 
    QComboBox *comBox = new QComboBox(this);
    comBox->addItem("短线");
    comBox->addItem("中线");
    comBox->addItem("长线");
    vb->addWidget(comBox);
 
    QPushButton *addBtn = new QPushButton("添加",this);
    vb->addWidget(addBtn);
 
    // 使用匿名函数来实现槽
    connect(addBtn,&QPushButton::clicked,this,[=]{
        QString name = m_lineEdits.at(0)->text();
        QString code = m_lineEdits.at(1)->text();
        QString price = m_lineEdits.at(2)->text();
        QString type = comBox->currentText();
        qDebug()<<name<<code<<price<<type;
        QString cur_time = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
 
        QString sql = QString("insert into position_pool (name,code,time_in,price_in,type,cur_price) values ('%1','%2','%3',%4,'%5',%6)")
                .arg(name).arg(code).arg(cur_time).arg(price).arg(type).arg(price);
        qDebug()<<"添加股票的sql:"<<sql;
 
        QSqlQuery que(db);
 
        if(que.exec(sql)){
            qDebug()<<"insert ok";
            QMessageBox::information(m_addDlg,"添加成功",name+" "+price);
 
        }else{
            qDebug()<<"insert fail"<<que.lastError().text();
            QMessageBox::information(m_addDlg,"添加失败",name+" "+que.lastError().text());
        }
 
    });
 
    // 右击菜单: 准备好菜单--给目标对象设置菜单策略为自定义上下文菜单--连接信号槽
    m_menu = new QMenu(this);
    m_menu->addAction("查询最新价格");
    m_menu->addAction("买入当前股票");
    m_menu->addAction("卖出当前股票");
 
    // 连接菜单动作和槽
    connect(m_menu->actions().at(0),SIGNAL(triggered(bool)),this,SLOT(searchPriceAction()));
    connect(m_menu->actions().at(1),SIGNAL(triggered(bool)),this,SLOT(buyStockAction()));
    connect(m_menu->actions().at(2),SIGNAL(triggered(bool)),this,SLOT(saleStockAction()));
 
 
    this->setContextMenuPolicy(Qt::CustomContextMenu); // 设定菜单策略
    ui->tableView_all->setContextMenuPolicy(Qt::CustomContextMenu);
    ui->tableView_short->setContextMenuPolicy(Qt::CustomContextMenu);
    ui->tableView_mid->setContextMenuPolicy(Qt::CustomContextMenu);
    ui->tableView_long->setContextMenuPolicy(Qt::CustomContextMenu);
 
    // 和窗口连接,在整个窗口中都可以右击显示菜单
//    connect(this,&PositionManagement::customContextMenuRequested,this,[=](QPoint p){
//        //m_menu->exec(QCursor::pos()); // 方式1
//        //m_menu->exec(this->mapToGlobal(p)); // 方式2,如果是子部件,容易坐标偏移
//        m_menu->popup(QCursor::pos()); // 换一个方式3 也可以
//    });
 
    // 和每个视图连接,只在视图中显示菜单
    connect(ui->tableView_all,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(showMenu(QPoint)));
    connect(ui->tableView_short,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(showMenu(QPoint)));
    connect(ui->tableView_mid,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(showMenu(QPoint)));
    connect(ui->tableView_long,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(showMenu(QPoint)));
 
 
 
}
 
PositionManagement::~PositionManagement()
{
    delete ui;
}
 
void PositionManagement::initMySQL()
{
    //添加一个数据库
    db=QSqlDatabase::addDatabase("QMYSQL");    //括号内要写出数据库的类型
    //设置数据库
    db.setHostName("127.0.0.1"); //设置数据库的主机ip
    //设置数据库的用户名
    db.setUserName("root");
    //设置数据库的密码
    db.setPassword("root");    //这个就是安装MySQL时设置的密码
    //设置数据库的名字
    db.setDatabaseName("stock_plan");
    //打开数据库(已经安装过mysql驱动了)
    if(db.open()==false){
        QMessageBox::warning(this,"waring",db.lastError().text());
    }else{
        qDebug()<<"mysql conn ok";
    }
}
 
void PositionManagement::on_pushButton_add_clicked()
{
    m_addDlg->show();
}
 
void PositionManagement::on_pushButton_refresh_clicked()
{
    m_modelAll->setRowCount(0);
    m_modelShort->setRowCount(0);
    m_modelMid->setRowCount(0);
    m_modelLong->setRowCount(0);
 
 
    QString sql = "select * from position_pool";
    QSqlQuery que(db);
    if(que.exec(sql)){
        qDebug()<<"查询成功";
 
        qDebug()<<"size:"<<que.size();
        while (que.next()) {
            QList<QStandardItem*> items;
            QList<QStandardItem*> items_short;
            QList<QStandardItem*> items_mid;
            QList<QStandardItem*> items_long;
            for(int i=0;i<15;++i){
                qDebug()<<i<<que.value(i).toString();
                items.append(new QStandardItem(que.value(i).toString()));
                items_short.append(new QStandardItem(que.value(i).toString()));
                items_mid.append(new QStandardItem(que.value(i).toString()));
                items_long.append(new QStandardItem(que.value(i).toString()));
 
            }
            m_modelAll->appendRow(items);
            if(items.at(12)->text() == "短线"){
                m_modelShort->appendRow(items_short);
            }else if(items.at(12)->text() == "中线"){
                m_modelMid->appendRow(items_mid);
            }else{
                m_modelLong->appendRow(items_long);
            }
        }
 
    }else{
        qDebug()<<"查询失败";
    }
}
 
void PositionManagement::showMenu(QPoint p)
{
    m_curPoint = p;  // 记录当前坐标--子部件内的坐标,刚好可用,不用再转换了
    m_curView = (QTableView*)sender(); // 记录被点击的视图,用来取索引--模型--数据
//    qDebug()<<sender()<<p;
//    qDebug()<<"显示右击菜单";
//    m_menu->exec(this->mapFromGlobal(p)); // 方式1,容易坐标跑偏,特别是子部件显示菜单时
    m_menu->exec(QCursor::pos());
 
 
 
}
 
void PositionManagement::searchPriceAction()
{
    qDebug()<<"查询最新价格"<<sender();
 
}
 
void PositionManagement::buyStockAction()
{
    qDebug()<<"买入当前股票";
    // 判断当前位置是否为选中的有效内容行,然后按当前价格买入即可,应该拿到最新价买卖
    // 一定要先判断状态是否为观察:观察的话--当前行买入,修改记录即可;如果是已经买入或卖出的状态,再添加一条新的买入记录
 
    QModelIndex index = m_curView->indexAt(m_curPoint);
    if(index.row() == -1) return; // 防止异常
 
    QStandardItemModel * curModel = (QStandardItemModel*)index.model();
    int row = index.row();
    QString id = curModel->item(row,0)->text();
    QString name = curModel->item(row,1)->text();
    QString code = curModel->item(row,2)->text();
    QString price = curModel->item(row,14)->text();
    QString state = curModel->item(row,13)->text();
    qDebug()<<id<<name<<code<<price<<"state:"<<state;
 
    if(state.toInt() == 1){
        // 更新当前即可,通过id来对比处理即可更新
        QString buy_time = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
        QString sql = QString("update position_pool set time_buy='%1',price_buy=%2,state=%4 where id=%3")
                .arg(buy_time).arg(price).arg(id).arg("2");
 
        qDebug()<<"buy sql:"<<sql;
 
        QSqlQuery que(db);
        if(que.exec(sql)){
            qDebug()<<"buy 成功:"<<name<<price;
            on_pushButton_refresh_clicked(); // 刷新股票池
        }else{
            qDebug()<<"buy 失败:"<<name<<price;
        }
 
    }else{
        // 创建新的记录,把当前价格和时间设置为入池、买入相应的价格和时间
    }
 
}
 
void PositionManagement::saleStockAction()
{
    qDebug()<<"卖出当前股票";
    // 判断当前位置是否为选中的有效内容行,然后按当前价格卖出即可,应该拿到最新价买卖
    // 一定要先判断出目前是买入持仓的状态,否则卖出失败
 
    QModelIndex index = m_curView->indexAt(m_curPoint);
    if(index.row() == -1) return; // 防止异常
 
    QStandardItemModel * curModel = (QStandardItemModel*)index.model();
    int row = index.row();
    QString id = curModel->item(row,0)->text();
    QString name = curModel->item(row,1)->text();
    QString code = curModel->item(row,2)->text();
    QString price = curModel->item(row,14)->text();
    QString state = curModel->item(row,13)->text();
    QString buy_price = curModel->item(row,6)->text();
    qDebug()<<id<<name<<code<<price<<"state:"<<state;
 
    if(state.toInt() == 2){
        // 更新当前即可,通过id来对比处理即可更新
        QString sell_time = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
        double rate = (price.toDouble() / buy_price.toDouble() - 1.0)*100; // 计算卖出盈利比
        QString sql = QString("update position_pool set time_sale='%1',price_sale=%2,state=%4,rate_sale=%7 where id=%3")
                .arg(sell_time).arg(price).arg(id).arg("3").arg(QString::number(rate));
 
        qDebug()<<"sell sql:"<<sql;
 
        QSqlQuery que(db);
        if(que.exec(sql)){
            qDebug()<<"sell 成功:"<<name<<price;
            on_pushButton_refresh_clicked(); // 刷新股票池
            QMessageBox::information(this,"卖出成功",name+" 盈利百分比:"+QString::number(rate));
        }else{
            qDebug()<<"sell 失败:"<<name<<price;
        }
 
    }else{
        qDebug()<<"不适合卖出,没有持仓";
        QMessageBox::information(this,"卖出失败","无持仓,不能卖出");
    }
}