一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C/C++中的 Qt StandardItemModel 數據模型應用解析

C/C++中的 Qt StandardItemModel 數據模型應用解析

2022-03-09 14:22Lyshark C/C++

QStandardItemModel 是標準的以項數據為單位的基于M/V模型的一種標準數據管理方式,本文給大家介紹C/C++中的 Qt StandardItemModel 數據模型應用解析,感興趣的朋友跟隨小編一起看看吧

qstandarditemmodel 是標準的以項數據為單位的基于m/v模型的一種標準數據管理方式,model/view 是qt中的一種數據編排結構,其中model代表模型,view代表視圖,視圖是顯示和編輯數據的界面組件,而模型則是視圖與原始數據之間的接口,通常該類結構都是用在數據庫中較多,例如模型結構負責讀取或寫入數據庫,視圖結構則負責展示數據,其條理清晰,編寫代碼便于維護。

qstandarditemmodel組件通常會配合tableview組件一起使用,當數據庫或文本中的記錄發生變化時會自動同步到組件中,首先繪制ui界面。

C/C++中的 Qt StandardItemModel 數據模型應用解析

其次綁定頂部toolbar菜單,分別對菜單增加對應的功能屬性的描述等。

C/C++中的 Qt StandardItemModel 數據模型應用解析

初始化構造函數: 當程序運行時,我們需要對頁面中的控件逐一初始化,并將table表格與模型通過調用ui->tableview->setmodel(model)進行綁定。

?
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
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
#include <iostream>
#include <qlabel>
#include <qstandarditem>
#include <qitemselectionmodel>
 
#include <qfiledialog>
#include <qtextstream>
 
#include <qlist>
 
// 默認構造函數
// https://www.cnblogs.com/lyshark
mainwindow::mainwindow(qwidget *parent): qmainwindow(parent), ui(new ui::mainwindow)
{
    ui->setupui(this);
 
    // 初始化部分
    model = new qstandarditemmodel(3,fixedcolumncount,this);  // 數據模型初始化
    selection = new qitemselectionmodel(model);               // item選擇模型
 
    // 為tableview設置數據模型
    ui->tableview->setmodel(model);               // 設置數據模型
    ui->tableview->setselectionmodel(selection);  // 設置選擇模型
 
    // 默認禁用所有action選項,只保留打開
    ui->actionsave->setenabled(false);
    ui->actionview->setenabled(false);
    ui->actionappend->setenabled(false);
    ui->actiondelete->setenabled(false);
    ui->actioninsert->setenabled(false);
 
    // 創建狀態欄組件,主要來顯示單元格位置
    labcurfile = new qlabel("當前文件:",this);
    labcurfile->setminimumwidth(200);
 
    labcellpos = new qlabel("當前單元格:",this);
    labcellpos->setminimumwidth(180);
    labcellpos->setalignment(qt::alignhcenter);
 
    labcelltext = new qlabel("單元格內容:",this);
    labcelltext->setminimumwidth(150);
 
    ui->statusbar->addwidget(labcurfile);
    ui->statusbar->addwidget(labcellpos);
    ui->statusbar->addwidget(labcelltext);
 
    //選擇當前單元格變化時的信號與槽
    connect(selection,signal(currentchanged(qmodelindex,qmodelindex)),this,slot(on_currentchanged(qmodelindex,qmodelindex)));
}
 
mainwindow::~mainwindow()
{
    delete ui;
}

初始化時同時需要綁定一個on_currentchanged(qmodelindex,qmodelindex)信號,當用戶選中指定單元格時相應用戶。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 選擇單元格變化時的響應,通過在構造函數中綁定信號和槽函數實現觸發
// https://www.cnblogs.com/lyshark
void mainwindow::on_currentchanged(const qmodelindex &current, const qmodelindex &previous)
{
   q_unused(previous);
 
    if (current.isvalid()) //當前模型索引有效
    {
        labcellpos->settext(qstring::asprintf("當前單元格:%d行,%d列",current.row(),current.column())); //顯示模型索引的行和列號
        qstandarditem   *aitem;
        aitem=model->itemfromindex(current); //從模型索引獲得item
        this->labcelltext->settext("單元格內容:"+aitem->text()); //顯示item的文字內容
    }
}

當頁面被初始化時,默認界面如下:

C/C++中的 Qt StandardItemModel 數據模型應用解析

打開并填充組件: 當工具欄中打開文件被點擊后則觸發,打開文件時通過afile.open打開,循環讀入文件,并將文件中的內容逐行追加到qstringlist ffilecontent中,當追加完畢后,直接調用inimodelfromstringlist(ffilecontent);完成對頁面tableview組件的初始化,并設置其他控件狀態為可點擊。

?
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
void mainwindow::on_actionopen_triggered()
{
    qstring curpath=qcoreapplication::applicationdirpath(); // 獲取應用程序的路徑
    
    // 調用打開文件對話框打開一個文件
    // https://www.cnblogs.com/lyshark
    qstring afilename=qfiledialog::getopenfilename(this,"打開一個文件",curpath,"數據文件(*.txt);;所有文件(*.*)");
    if (afilename.isempty())
    {
        return; // 如果未選擇文件則退出
    }
 
    qstringlist ffilecontent;                              // 文件內容字符串列表
    qfile afile(afilename);                                // 以文件方式讀出
    if (afile.open(qiodevice::readonly | qiodevice::text)) // 以只讀文本方式打開文件
    {
        qtextstream astream(&afile);       // 用文本流讀取文件
        ui->plaintextedit->clear();        // 清空列表
 
        // 循環讀取只要不為空
        while (!astream.atend())
        {
            qstring str=astream.readline();          // 讀取文件的一行
            ui->plaintextedit->appendplaintext(str); // 添加到文本框顯示
            ffilecontent.append(str);                // 添加到stringlist
        }
        afile.close();                               // 關閉文件
 
        inimodelfromstringlist(ffilecontent);        // 從stringlist的內容初始化數據模型
    }
 
    // 打開文件完成后,就可以將action全部開啟了
    ui->actionsave->setenabled(true);
    ui->actionview->setenabled(true);
    ui->actionappend->setenabled(true);
    ui->actiondelete->setenabled(true);
    ui->actioninsert->setenabled(true);
 
    // 打開文件成功后,設置狀態欄當前文件列
    this->labcurfile->settext("當前文件:"+afilename);//狀態欄顯示
}

如上inimodelfromstringlist(ffilecontent);函數是后期增加的,我們需要自己實現,該函數的作用是從傳入的stringlist中獲取數據,并將數據初始化到tableview模型中,實現代碼如下。

?
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
void mainwindow::inimodelfromstringlist(qstringlist& afilecontent)
{
    int rowcnt=afilecontent.count();     // 文本行數,第1行是標題
    model->setrowcount(rowcnt-1);        // 實際數據行數,要在標題上減去1
 
    // 設置表頭
    qstring header=afilecontent.at(0);         // 第1行是表頭
 
    // 一個或多個空格、tab等分隔符隔開的字符串、分解為一個stringlist
    // https://www.cnblogs.com/lyshark
    qstringlist headerlist=header.split(qregexp("\\s+"),qstring::skipemptyparts);
    model->sethorizontalheaderlabels(headerlist); // 設置表頭文字
 
    // 設置表格中的數據
    int x = 0,y = 0;
    qstandarditem *item;
 
    // 有多少列數據就循環多少次
    // https://www.cnblogs.com/lyshark
    for(x=1; x < rowcnt; x++)
    {
        qstring linetext = afilecontent.at(x);    // 獲取數據區的一行
 
        // 一個或多個空格、tab等分隔符隔開的字符串、分解為一個stringlist
        qstringlist tmplist=linetext.split(qregexp("\\s+"),qstring::skipemptyparts);
 
        // 循環列數,也就是循環fixedcolumncount,其中tmplist中的內容也是.
        for(y=0; y < fixedcolumncount-1; y++)
        {
            item = new qstandarditem(tmplist.at(y)); // 創建item
            model->setitem(x-1,y,item);              // 為模型的某個行列位置設置item
        }
 
        // 最后一個數據需要取出來判斷,并單獨設置狀態
        item=new qstandarditem(headerlist.at(y));   // 最后一列是checkable,需要設置
        item->setcheckable(true);                   // 設置為checkable
 
        // 判斷最后一個數值是否為0
        if (tmplist.at(y) == "0")
            item->setcheckstate(qt::unchecked);   // 根據數據設置check狀態
        else
            item->setcheckstate(qt::checked);
 
        model->setitem(x-1,y,item); //為模型的某個行列位置設置item
    }
}

初始化組件后效果如下:

C/C++中的 Qt StandardItemModel 數據模型應用解析

實現添加一行數據: 為tableview添加一行數據,在文件末尾插入。

?
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
void mainwindow::on_actionappend_triggered()
{
    qlist<qstandarditem *> itemlist;   // 創建臨時容器
    qstandarditem *item;
 
    // 模擬添加一列的數據
    for(int x=0; x<fixedcolumncount-1; x++)
    {
        item = new qstandarditem("測試(追加行)");    // 循環創建每一列
        itemlist << item;                          // 添加到鏈表中
    }
 
    // 創建最后一個列元素,由于是選擇框所以需要單獨創建
    // https://www.cnblogs.com/lyshark
    // 1.獲取到最后一列的表頭下標,最后下標為6
    qstring str = model->headerdata(model->columncount()-1,qt::horizontal,qt::displayrole).tostring();
 
    item=new qstandarditem(str); // 創建 "是否合格" 字段
    item->setcheckable(true);    // 設置狀態為真
    itemlist << item;            // 最后一個選項追加進去
 
    model->insertrow(model->rowcount(),itemlist);                 // 插入一行,需要每個cell的item
    qmodelindex curindex=model->index(model->rowcount()-1,0);     // 創建最后一行的modelindex
 
    selection->clearselection();                                      // 清空當前選中項
    selection->setcurrentindex(curindex,qitemselectionmodel::select); // 設置當前選中項為當前選擇行
}

插入代碼演示效果:

C/C++中的 Qt StandardItemModel 數據模型應用解析

實現插入一行數據: 為tableview插入一行數據(在文件任意位置插入數據)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// https://www.cnblogs.com/lyshark
void mainwindow::on_actioninsert_triggered()
{
    qlist<qstandarditem*> itemlist;       // qstandarditem的列表類
    qstandarditem *item;
 
    // 模擬插入前五列數據
    for(int i=0;i<fixedcolumncount-1;i++)
    {
        item= new qstandarditem("測試(插入行)");  // 新建一個qstandarditem
        itemlist << item;                        // 添加到列表類
    }
 
    qstring str;                               // 獲取表頭文字
    str=model->headerdata(model->columncount()-1,qt::horizontal,qt::displayrole).tostring();
    item=new qstandarditem(str);      // 創建item
    item->setcheckable(true);         // 設置為可使用checkbox
    itemlist<<item;                   // 添加到列表類
 
    qmodelindex curindex=selection->currentindex(); // 獲取當前選中項的索引
    model->insertrow(curindex.row(),itemlist);      // 在當前行的前面插入一行
    selection->clearselection();                                       // 清除當前選中項
    selection->setcurrentindex(curindex,qitemselectionmodel::select);  // 設置當前選中項為當前選擇行
}

插入代碼演示效果:

C/C++中的 Qt StandardItemModel 數據模型應用解析

實現刪除一行數據: 刪除數據之前需要通過selection->currentindex()確定當前選中行,并通過model->removerow()移除即可。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// https://www.cnblogs.com/lyshark
void mainwindow::on_actiondelete_triggered()
{
    qmodelindex curindex = selection->currentindex();  // 獲取當前選擇單元格的模型索引
 
    // 先判斷是不是最后一行
    if (curindex.row()==model->rowcount()-1)
    {
        model->removerow(curindex.row()); //刪除最后一行
    }
    else
    {
        model->removerow(curindex.row());//刪除一行,并重新設置當前選擇行
        selection->setcurrentindex(curindex,qitemselectionmodel::select);
    }
}<br>

刪除代碼效果演示:

C/C++中的 Qt StandardItemModel 數據模型應用解析

實現字體數據對齊: 表格中的字體可以實現多種對其方式,對齊方式分為 居中對齊,左對齊,右對齊 三種。

?
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
// 設置表格居中對齊
void mainwindow::on_pushbutton_clicked()
{
    if (!selection-&gt;hasselection())
        return;
 
    qmodelindexlist selectedindex=selection-&gt;selectedindexes();
 
    qmodelindex index;
    qstandarditem *item;
 
    for (int i=0; i&lt;selectedindex.count(); i++)
    {
        index=selectedindex.at(i);
        item=model-&gt;itemfromindex(index);
        item-&gt;settextalignment(qt::alignhcenter);
    }
}
 
// 設置表格左對齊
// https://www.cnblogs.com/lyshark
void mainwindow::on_pushbutton_2_clicked()
{
    if (!selection-&gt;hasselection()) //沒有選擇的項
        return;
 
//獲取選擇的單元格的模型索引列表,可以是多選
    qmodelindexlist selectedindex=selection-&gt;selectedindexes();
 
    for (int i=0;i&lt;selectedindex.count();i++)
    {
        qmodelindex aindex=selectedindex.at(i); //獲取其中的一個模型索引
        qstandarditem* aitem=model-&gt;itemfromindex(aindex);//獲取一個單元格的項數據對象
        aitem-&gt;settextalignment(qt::alignleft);//設置文字對齊方式
    }
}
 
// 設置表格右對齊
void mainwindow::on_pushbutton_3_clicked()
{
    if (!selection-&gt;hasselection())
        return;
 
    qmodelindexlist selectedindex=selection-&gt;selectedindexes();
 
    qmodelindex aindex;
    qstandarditem *aitem;
 
    for (int i=0;i&lt;selectedindex.count();i++)
    {
        aindex=selectedindex.at(i);
        aitem=model-&gt;itemfromindex(aindex);
        aitem-&gt;settextalignment(qt::alignright);
    }
}

對齊代碼效果演示:

C/C++中的 Qt StandardItemModel 數據模型應用解析

實現字體數據加粗: 將選中行的字體進行加粗顯示。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 設置字體加粗顯示
// https://www.cnblogs.com/lyshark
void mainwindow::on_pushbutton_4_clicked()
{
    if (!selection-&gt;hasselection())
        return;
 
//獲取選擇單元格的模型索引列表
    qmodelindexlist selectedindex=selection-&gt;selectedindexes();
 
    for (int i=0;i&lt;selectedindex.count();i++)
    {
        qmodelindex aindex=selectedindex.at(i); //獲取一個模型索引
        qstandarditem* aitem=model-&gt;itemfromindex(aindex);//獲取項數據
        qfont font=aitem-&gt;font(); //獲取字體
        font.setbold(true); //設置字體是否粗體
        aitem-&gt;setfont(font); //重新設置字體
    }

加粗代碼效果演示:

C/C++中的 Qt StandardItemModel 數據模型應用解析

實現保存文件: 當保存文件被點擊后觸發,通過便利tablewidget模型組件中的數據,并將數據通過astream << str << "\n";寫出到記事本中。

?
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
// https://www.cnblogs.com/lyshark
// 【保存文件】
void mainwindow::on_actionsave_triggered()
{
    qstring curpath=qcoreapplication::applicationdirpath(); // 獲取應用程序的路徑
 
    // 調用打開文件對話框選擇一個文件
    qstring afilename=qfiledialog::getsavefilename(this,tr("選擇一個文件"),curpath,"數據文件(*.txt);;所有文件(*.*)");
 
    if (afilename.isempty()) // 未選擇文件則直接退出
        return;
 
    qfile afile(afilename);
 
    // 以讀寫、覆蓋原有內容方式打開文件
    if (!(afile.open(qiodevice::readwrite | qiodevice::text | qiodevice::truncate)))
        return;
 
    qtextstream astream(&amp;afile);    // 用文本流讀取文件
    qstandarditem *item;
    qstring str;
    int x = 0,y = 0;
 
    ui-&gt;plaintextedit-&gt;clear();
 
// 獲取表頭文字
    for (x=0; x&lt;model-&gt;columncount(); x++)
    {
        item=model-&gt;horizontalheaderitem(x);     // 獲取表頭的項數據
        str= str + item-&gt;text() + "\t\t";        // 以tab制表符隔開
    }
    astream &lt;&lt; str &lt;&lt; "\n";                      // 文件里需要加入換行符\n
    ui-&gt;plaintextedit-&gt;appendplaintext(str);
 
// 獲取數據區文字
    for ( x=0; x &lt; model-&gt;rowcount(); x++)
    {
        str = "";
        for( y=0; y &lt; model-&gt;columncount()-1; y++)
        {
            item=model-&gt;item(x,y);
            str=str + item-&gt;text() + qstring::asprintf("\t\t");
        }
 
        // 對最后一列需要轉換一下,如果判斷為選中則寫1否則寫0
        item=model-&gt;item(x,y);
        if (item-&gt;checkstate()==qt::checked)
            str= str + "1";
        else
            str= str + "0";
 
         ui-&gt;plaintextedit-&gt;appendplaintext(str);
         astream &lt;&lt; str &lt;&lt; "\n";
    }
}
 
// 【導出txt文件】:將tableview中的數據導出到plaintextedit顯示
void mainwindow::on_actionview_triggered()
{
        ui-&gt;plaintextedit-&gt;clear();
        qstandarditem *item;
        qstring str;
 
    //獲取表頭文字
        int x=0,y=0;
        for (x=0; x&lt;model-&gt;columncount(); x++)
        { //
            item=model-&gt;horizontalheaderitem(x);
            str= str + item-&gt;text() + "\t";
        }
        ui-&gt;plaintextedit-&gt;appendplaintext(str);
 
    //獲取數據區的每行
        for (x=0; x&lt;model-&gt;rowcount(); x++)
        {
            str="";
            for(y=0; y&lt;model-&gt;columncount()-1; y++)
            {
                item=model-&gt;item(x,y);
                str= str + item-&gt;text() + qstring::asprintf("\t");
            }
 
            item=model-&gt;item(x,y);
            if (item-&gt;checkstate()==qt::checked)
                str= str + "1";
            else
                str= str + "0";
 
             ui-&gt;plaintextedit-&gt;appendplaintext(str);
        }
}

文件保存后如下:

C/C++中的 Qt StandardItemModel 數據模型應用解析

到此這篇關于c/c++中的 qt standarditemmodel 數據模型應用解析的文章就介紹到這了,更多相關c++ qt standarditemmodel 數據模型內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/LyShark/p/15637813.html

延伸 · 閱讀

精彩推薦
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
主站蜘蛛池模板: naruto tube18动漫 mm131亚洲精品久久 | 99久久精品免费观看区一 | 国产成人综合精品一区 | 丝瓜污污 | 国产亚洲女人久久久久久 | xnxx动漫| 久草草在线视视频 | 91精品国产综合久久 | 视频在线观看一区二区三区 | 国产午夜亚洲精品不卡 | 91日本 | 亚瑟天堂久久一区二区影院 | 男男羞羞视频网站国产 | 亚洲一级特黄 | 啊哈~嗯哼~用力cao我小说 | 喜爱夜蒲2三级做爰 | 国产福利一区二区精品视频 | 国产馆精品推荐在线观看 | a性片| 奇米影视亚洲狠狠色 | 毛片视频在线免费观看 | 国内精品久久久久久中文字幕 | 变态 另类 国产 亚洲 | 男人午夜禁片在线观看 | 精品一区二区国语对白 | 美女伊人网 | 成人毛片1024你懂的 | 国内精品久久久久久中文字幕 | 亚洲欧美成人综合在线 | 久久久久免费视频 | 免费一级国产生活片 | 国自产精品手机在线视频 | 肉色欧美久久久久久久蜜桃 | 热久久亚洲 | 91精品国产免费久久 | 精品久久久久久久久免费影院 | 国产精品亚洲精品日韩已方 | 青青草原手机在线视频 | 亚洲欧美日韩精品高清 | 国产精品va在线观看手机版 | 色无月|