IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 利用QT Creator(4.13.1)开发基于C++语言的C语言集成开发环境(IDE) -> 正文阅读

[C++知识库]利用QT Creator(4.13.1)开发基于C++语言的C语言集成开发环境(IDE)

目录

前言

一、QT Creator 的概述

(一)QT Creator 的介绍

(二)?QT Creator 的历史

(三)下载与安装

?1.下载地址:

2.安装:?默认安装(建议组件全部选中)

(四)成功案例

二、基本功能性能要求

(一)基本功能要求:

1.提供基本编辑功能:

2.提供编译运行功能:

(二)基本性能要求

三、开发过程

(一)项目建立及框架构建

1.建立项目

2.框架构建

(二)各项基本功能的建立

1.新建

?2.打开

3.保存?

?4.退出

?5.另存为

?6.撤销

7.复制拷贝

8.剪切+粘贴?

?9.编译

10.?查找

11.停止查找

12.查找下一个

13.全文替换

14.结束替换

15.插入各组槽函数(DATA、for循环、while循环、do_while循环、switch、if、Class)?

?(三)部分实用小功能的添加

1.快捷键的添加

?2.字体设置

?3.工具栏图片资源添加

?三、运行效果

?

总结


?


前言

? ? ? 同学们在学习完C++后都不免有许多疑惑。例如,有些简单的能用C语言解决的问题为什么要用C++呢?学习了C++语言我该怎么使用呢?C++语言的优势如何体现呢?

? ? ? 接下来,作者将以一个实例(利用QT Creator 4.13.1开发基于C++语言的C语言集成开发环境)体现C++语言的优势。因此本文主要讲的是如何开发一个简易的C语言IDE。而同学们需要跟着学习制作这个简易的IDE以体会C++语言的优势所在。




一、QT Creator 的概述

(一)QT Creator 的介绍

? ? ?Qt Creator是跨平台的 Qt IDE, Qt Creator 是 Qt 被?Nokia?收购后推出的一款新的轻量级集成开发环境(IDE)。此 IDE 能够跨平台运行,支持的系统包括 Linux(32 位及 64 位)、Mac OS X 以及 Windows。根据官方描述,Qt Creator 的设计目标是使开发人员能够利用 Qt 这个应用程序框架更加快速及轻易的完成开发任务。?

? ? ?Qt Creator 包括项目生成向导、高级的 C++ 代码编辑器、浏览文件及类的工具、集成了 Qt Designer、Qt Assistant、Qt Linguist(里边的QT助手在开发过程中很有帮助)、图形化的 GDB 调试前端,集成 qmake 构建工具等。

(二)?QT Creator 的历史

1991年 Qt最早由奇趣科技开发

1996年?进入商业领域,它也是目前流行的Linux桌面环境KDE的基础

2008年?奇趣科技被诺基亚公司收购,Qt称为诺基亚旗下的编程语言

2012年 Qt又被Digia公司收购

2014年4月 跨平台的集成开发环境Qt Creator3.1.0发布,同年5月20日配发了Qt5.3正式版,至此Qt实现了对iOS、Android、WP等各平台的全面支持。

(三)下载与安装

?1.下载地址:

www.qt.io/download-open-source/http://www.qt.io/download-open-source/

2.安装:?默认安装(建议组件全部选中)

(详细的QT Creator基础使用手册私信请作者获取)

(四)成功案例

  1. Linux桌面环境KDE
  2. WPS Office 办公软件
  3. Skype 网络电话
  4. Google Earth 谷歌地图
  5. VLC多媒体播放器
  6. VirtualBox虚拟机软件

?废话不多说,进入正题~


?



二、基本功能性能要求

? 编写一个简单的C语言集成开发环境IDE?



(一)基本功能要求:

1.提供基本编辑功能:

  • 支持键盘/鼠标操作,必要的菜单操作
  • 建立文件,保存/打开/另存/关闭
  • 对字符/串的插入、删除、查找、替换
  • 对文本块的复制、粘贴、剪切?

2.提供编译运行功能:

  • 能够进行编译/链接,并反馈编译结果

  • 对通过 编译的程序投入运行并给出执行结果

(二)基本性能要求

  • 支持单文件编辑,文本长度不超过2000行

  • 装入/保存2000行源程序

  • 基本操作(插入/删除/查找等)响应无明显延迟?




三、开发过程

? ? 1.在开发之前同学们需要利用学习手册先了解QT Creator 的一些基本操作。(学习手册私信作者获取)

? ? 2.安装好Linguist 5.12.10 (MSVC 2017 64-bit),开发过程有不懂的地方都可以在上面查找。

? ? ? ?QT助手打开方式:打开Linguist -> 点击菜单栏的“帮助” -> 点击 QT 助手;

结果如下图:

(可以在左侧查找框搜索所需内容)

(一)项目建立及框架构建

1.建立项目

? ?选用ui设计师模式对界面基本框架进行构建,添加相应的菜单栏、工具栏、文本编辑框、状态栏等。

? ? mainwindow.cpp中加入相应初始化代码:

    ui->setupUi(this);
    setCentralWidget(ui->textEdit);//自适应窗口大小
    flag=utf8;//初始化,默认flag显示utf-8
    codec=QTextCodec::codecForName("gbk"); //字符编码指针初始化

    QString  str;
    str=ui->textEdit->toPlainText();
    path="";

2.框架构建

? ?(1)“文件”菜单项内容添加:

(2)“编辑”菜单项内容添加:

(3)“编译”菜单项无子菜单项

(二)各项基本功能的建立

? ? ? 对各项功能的建立即槽函数的填充,?QT Creator 最核心的就是信号与槽的概念。在ui设计界面的下端排列有建立的action,右键点击其中一栏,点击“转到槽”即可跳转到该action槽函数的设置。

? ? ? 各个功能槽函数都在下面给出,并由相应注释进行解释。

? ? ? QT的语言库中包含了非常丰富的函数库,同学们可以在QT助手当中查找相应用法并加以利用。

1.新建

? ? ?方便后边使用,在mainwindow.cpp 中添加可能会用到的头文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QDebug>
#include <QTextCodec>
#include <string.h>
#include <QLineEdit>
#include <QDialog>
#include <QPushButton>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QTextCursor>
#include <QPlainTextEdit>
#include <QLabel>
#include <QDateTime>
#include <QTextCharFormat>
#include <QFontDialog>
#include <QToolBar>

? ? ?“建立”功能槽函数:

    ui->textEdit->clear();
    path="";

?2.打开

   path=QFileDialog::getOpenFileName();//打开一个文件,获取此文件目录
   if(path.isEmpty()) {return;}//如果没有选择路径
   char *fileName= codec->fromUnicode(path).data();
   FILE* fp=fopen(fileName,"rb");//打开文件,fopen(),如果有中文,需要gbk
   if(fp==NULL){            //打开失败
        return;
    }//循环读取文件内容fgets(),读取内容char*
   char buf[2048];QString str="";//读之前,清空buf内容
   while(1)
    {
        memset(buf,0,sizeof(buf));
        fgets(buf,sizeof(buf),fp);
        if(flag==utf8){str=str+buf;}
          else if(flag==gbk)
              {
                str=str+codec->toUnicode(buf);
              }
        if(feof(fp)) {break;}            //如果文件结束,结束循环
    }
   ui->textEdit->setText(str);//需要把读取的内容给编辑区设置setText

3.保存?

    if(path.isEmpty())//如果路径为空,没选择路径,需选择路径
   {     path=QFileDialog::getSaveFileName();//不空,将内容保存到原来的路径  打开文件,获取编辑器内容 保存文件  关闭文件
         if(path.isEmpty()) {return;}
   }
    char *fileName=codec->fromUnicode(path).data();//将utf-8替换成gbk,同时将QString转换为char*
    FILE* fp=fopen(fileName,"wb");//打开文件,fopen(),需要的路径为char*,有中文要gbk

    if(fp==NULL) {return;}//打开失败

    QString str=ui->textEdit->toPlainText();//获取编辑区内容QString

    const char * buf=str.toStdString().data();//将编辑区内容QString转为char*

    fputs(buf,fp);//将编辑区内容写入文件fputs

    fclose(fp);//关闭文件

?4.退出

exit(0);

?5.另存为

    path=QFileDialog::getSaveFileName();//选择文件保存路径
    if(path.isEmpty()) {return;}
    qDebug()<<path;

    char *fileName=codec->fromUnicode(path).data();//将utf-8替换成gbk,同时将QString转换为char*

    FILE* fp=fopen(fileName,"wb");//打开文件,fopen(),需要的路径为char*,有中文要gbk
    if(fp==NULL) {return;}//打开失败

        QString str=ui->textEdit->toPlainText();//获取编辑区内容QString

        const char * buf=str.toStdString().data();//将编辑区内容QString转为char*

        fputs(buf,fp);//将编辑区内容写入文件fputs

        fclose(fp);//关闭文件

?6.撤销

ui->textEdit->undo();

7.复制拷贝

ui->textEdit->copy();

8.剪切+粘贴?

? ?剪切:

ui->textEdit->cut();

? ?粘贴:

ui->textEdit->paste();

?9.编译

        if(path.isEmpty()) {                //已经完成编写,但还未保存,则先进行保存操作
            if(ui->textEdit->document()->isEmpty()){return;};
            path=QFileDialog::getSaveFileName();
            if(path.isEmpty()) {return;}//路径为空则返回,不空,将内容保存到原来的路径  打开文件,获取编辑器内容 保存文件  关闭文件

            char *fileName=codec->fromUnicode(path).data();//将utf-8替换成gbk,同时将QString转换为char*

            FILE* fp=fopen(fileName,"wb");//打开文件,fopen(),需要的路径为char*,有中文要gbk
            if(fp==NULL) {return;}//打开失败

                QString str=ui->textEdit->toPlainText();//获取编辑区内容QString

                const char * buf=str.toStdString().data();//将编辑区内容QString转为char*

                fputs(buf,fp);//将编辑区内容写入文件fputs

                fclose(fp);//关闭文件
        }
        QString demo=path;
        demo.replace(".c","");//将demo内部的字符.c替换为空字符
        QString cmd=QString ("gcc %1 -o %2").arg(path).arg(demo);//如果有中文,需要gbk,同时将QString转化为char*


        int ret=system(codec->fromUnicode(cmd).data());//如果编码正确,system返回值为0
        if(ret!=0){                                    //如果代码出错,再编译一次

            cmd=QString ("cmd /k gcc %1 -o %2").arg(path).arg(demo);
            system(codec->fromUnicode(cmd).data());
            return;}

        QString target=QString ("cmd/k %1").arg(demo);//执行到这一步,编译成功,需要执行程序

        system(codec->fromUnicode(target).data());

10.?查找

? ? ? 在mainwindow.h头文件中的私有成员处声明全局变量:(由于涉及到查找的一些其他操作,因此一下变量需设置成全局变量)

    QLineEdit *findLineEdit;
    QDialog *findDlg;

? ? ? mainwindow.cpp源文件中的构造函数:

    findDlg = new QDialog(this);//创建对话框
    findDlg->setWindowTitle(tr("查找"));//设置对话框标题
    findLineEdit = new QLineEdit(findDlg);//创建QLineEdit
    QPushButton *btn= new QPushButton(tr("查找"), findDlg);//创建查找按钮
    QPushButton *btn1= new QPushButton(tr("结束查找"), findDlg);//创建结束查找按钮
    QPushButton *btn2= new QPushButton(tr("查找下一个"), findDlg);//创建查找下一个按钮
    QVBoxLayout *layout= new QVBoxLayout(findDlg);//创建layaout
    layout->addWidget(findLineEdit);//将创建的QLineEdit、Button放置在layout上
    layout->addWidget(btn);
    layout->addWidget(btn2);
    layout->addWidget(btn1);
    connect(btn, SIGNAL(clicked()), this, SLOT(on_actionchao_triggered()));//连接
    connect(btn1, SIGNAL(clicked()), this, SLOT(tingzhicahzhao ()));
    connect(btn2, SIGNAL(clicked()), this, SLOT(chazhaoxiayige ()));

? ? ?查找槽函数:

            int flag=0;
            findDlg->setFixedSize(400,300);
            findDlg->show();//显示对话框
            QString str=findLineEdit->text();//获取输入的string
            QTextDocument *document = ui->textEdit->document();//定义QTextDocunment对象
            bool found = false;
            QTextCursor highlight_cursor(document);
            QTextCharFormat color_format(highlight_cursor.charFormat());
            color_format.setForeground(Qt::black);   //设置字体颜色
            color_format.setBackground(Qt::yellow);  //设置背景颜色
            while (!highlight_cursor.isNull() && !highlight_cursor.atEnd()&&str!="")
            {
                //查找指定的文本,匹配整个单词
                highlight_cursor = document->find(str, highlight_cursor, QTextDocument::FindWholeWords);
                if (!highlight_cursor.isNull())
                {
                    if (!found) found = true;
                    highlight_cursor.mergeCharFormat(color_format),flag++;
                }
            }
            if(flag==0&&str!="") {
                QMessageBox::warning(this, tr("查找"),tr("找不到%1").arg(str));
            }

11.停止查找

     QString str1=findLineEdit->text();
     QTextDocument *document = ui->textEdit->document();
     bool found = false;
     QTextCursor highlight_cursor(document);
     QTextCharFormat color_format(highlight_cursor.charFormat());
     color_format.setForeground(Qt::black);   //字体颜色
     color_format.setBackground(Qt::white);  //背景颜色
     while (!highlight_cursor.isNull() && !highlight_cursor.atEnd()&&str1!="")
     {
         //查找指定的文本,匹配整个单词
         highlight_cursor = document->find(str1, highlight_cursor, QTextDocument::FindWholeWords);
         if (!highlight_cursor.isNull())
         {
             if (!found) found = true;
             highlight_cursor.mergeCharFormat(color_format);
         }
     }
     findLineEdit->clear();
     findDlg->close();

12.查找下一个

    QString str2=findLineEdit->text();
    QTextDocument *document = ui->textEdit->document();
    bool found = false;
    QTextCursor highlight_cursor(document);
    QTextCharFormat color_format(highlight_cursor.charFormat());
    color_format.setForeground(Qt::black);   //字体颜色
    color_format.setBackground(Qt::white);  //背景颜色
    while (!highlight_cursor.isNull() && !highlight_cursor.atEnd()&&str2!="")
    {
        //查找指定的文本,匹配整个单词
        highlight_cursor = document->find(str2, highlight_cursor, QTextDocument::FindWholeWords);
        if (!highlight_cursor.isNull())
        {
            if (!found) found = true;
            highlight_cursor.mergeCharFormat(color_format);
        }
    }
    findLineEdit->clear();

13.全文替换

?? ? ? 在mainwindow.h头文件中的私有成员处声明全局变量:(由于涉及到替换的一些其他操作,因此一下变量需设置成全局变量)

    QDialog *replaceDlg;
    QLineEdit *replaceLineEdit_1;
    QLineEdit *replaceLineEdit_2;

? ? ?mainwindow.cpp源文件中构造函数所需加入内容:

    replaceDlg=new QDialog;
    replaceDlg->setWindowTitle("全文替换");
    QLabel *Rlable_1= new QLabel(tr("想用:"), replaceDlg);
    replaceLineEdit_1 =new QLineEdit(replaceDlg);
    QLabel *Rlable_2= new QLabel(tr("替换:"), replaceDlg);
    replaceLineEdit_2 =new QLineEdit(replaceDlg);
    QVBoxLayout *Rlayout= new QVBoxLayout(replaceDlg);
    Rlayout->addWidget(Rlable_1);
    Rlayout->addWidget(replaceLineEdit_1);
    Rlayout->addWidget(Rlable_2);
    Rlayout->addWidget(replaceLineEdit_2);
    QPushButton *Rbtn_1= new QPushButton(tr("替换!"), replaceDlg);
    QPushButton *Rbtn_2= new QPushButton(tr("结束替换"), replaceDlg);
    Rlayout->addWidget(Rbtn_1);
    Rlayout->addWidget(Rbtn_2);
    connect(Rbtn_1, SIGNAL(clicked()), this, SLOT(on_actionhuan_triggered()));
    connect(Rbtn_2, SIGNAL(clicked()), this, SLOT(jieshutihuan()));

?全文替换函数:

    replaceDlg->setFixedSize(400,300);
    replaceDlg->show();
    QString str1=replaceLineEdit_1->text();
    QString str2=replaceLineEdit_2->text();
    QString str3;
    QTextDocument *document = ui->textEdit->document();
    bool found = false;
    QTextCursor replace_cursor(document);
    while (!replace_cursor.isNull() && !replace_cursor.atEnd()&&str2!=""&&str1!="")
    {
        //查找指定的文本,匹配整个单词
        replace_cursor = document->find(str2, replace_cursor, QTextDocument::FindWholeWords);
        if (!replace_cursor.isNull())
        {
            if (!found) found = true;
            replace_cursor.removeSelectedText();
            replace_cursor.insertText(str1);
        }
    }
    replaceLineEdit_1->clear(),replaceLineEdit_2->clear();

14.结束替换

    replaceDlg->close();

15.插入各组槽函数(DATA、for循环、while循环、do_while循环、switch、if、Class)?

/*insert部分中的Date*/
void MainWindow::on_actionDate_triggered()
{
    QTextDocument *document = ui->textEdit->document();//获取文档
    QTextCursor Datecursor(document);//定义光标
    QString Date;//定义承接时间的字符串
    Date = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");//获取系统时间
    Datecursor.insertText(Date);//再光标处插入系统时间
}


/*insert部分中的for循环*/
void MainWindow::on_actionfor_triggered()
{
    QTextDocument *document = ui->textEdit->document();//获取文档
    QTextCursor for_cursor(document);//定义光标
    QString for_string="for(;;){\n}";
    for_cursor.insertText(for_string);
}


/*insert部分中的while循环*/
void MainWindow::on_actionwhile_triggered()
{
    QTextDocument *document = ui->textEdit->document();//获取文档
    QTextCursor while_cursor(document);//定义光标
    QString while_string="while(){\n}";
    while_cursor.insertText(while_string);
}


/*insert部分中的do_while循环*/
void MainWindow::on_actiondo_while_triggered()
{
    QTextDocument *document = ui->textEdit->document();//获取文档
    QTextCursor do_while_cursor(document);//定义光标
    QString do_while_string="do {\n} while();";
    do_while_cursor.insertText(do_while_string);
}


/*insert部分中的if*/
void MainWindow::on_actionif_triggered()
{
    QTextDocument *document = ui->textEdit->document();//获取文档
    QTextCursor if_cursor(document);//定义光标
    QString if_string="if() {\n}";
    if_cursor.insertText(if_string);
}


/*insert部分中的switch*/
void MainWindow::on_actionswitch_triggered()
{
    QTextDocument *document = ui->textEdit->document();//获取文档
    QTextCursor switch_cursor(document);//定义光标
    QString switch_string="switch() {\n	default:\n}";
    switch_cursor.insertText(switch_string);
}


/*insert部分中的Class*/
void MainWindow::on_actionClass_triggered()
{
    QTextDocument *document = ui->textEdit->document();//获取文档
    QTextCursor Class_cursor(document);//定义光标
    QString Class_string="class  {\n	// Private section\n	public:\n		// Public Declarations\n	protected:\n		// Protected Declarations\n};";
    Class_cursor.insertText(Class_string);
}

?(三)部分实用小功能的添加

1.快捷键的添加

? ? mainwindow.cpp中的构造函数:

    ui->actionnew->setShortcut(tr("Ctrl+n"));//新建
    ui->action_11->setShortcut(tr("Ctrl+o"));//打开
    ui->action1->setShortcut(tr("Ctrl+s"));//保存
    ui->actionlingcunwei->setShortcut(tr("Ctrl+Shift+s"));//另存为
    ui->actiontui->setShortcut(tr("Esc"));//退出
    ui->actionchexiao->setShortcut(tr("Ctrl+u"));//撤销
    ui->actionfuzhi->setShortcut(tr("Ctrl+c"));//复制
    ui->actionzhantie->setShortcut(tr("Ctrl+v"));//粘贴
    ui->actionjianqie->setShortcut(tr("Ctrl+p"));//剪切
    ui->actionbianyi->setShortcut(tr("Ctrl+Shift+c"));//编译
    ui->actionchao->setShortcut(tr("Ctrl+f"));//查找
    ui->actionhuan->setShortcut(tr("Ctrl+r"));//替换

?2.字体设置

槽函数:

    QTextCharFormat fmt;
    bool ok;
    QFont font = QFontDialog::getFont(&ok, QFont("Consolas",9), this,"设置显示字体");
    fmt.setFont(font);
    ui->textEdit->setCurrentCharFormat(fmt);

?3.工具栏图片资源添加

? ? 在工具栏上,每个按钮都是以文字显示,为了美观我们也可以添加图片资源,并建立按钮与某张图片的联系。

? ? mainwindow.cpp中的构造函数:

/*工具栏图片资源添加*/

    ui->actionnew->setIcon(QIcon(":/new/xinjian1.png"));
    ui->actionchexiao->setIcon(QIcon(":/new/qianfanye.png"));
    ui->actionredo->setIcon(QIcon(":/new/houfanye.png"));
    ui->action1->setIcon(QIcon(":/new/baocun.png"));
    ui->actionbianyi->setIcon(QIcon(":/new/bianyi.png"));
    ui->actionlingcunwei->setIcon(QIcon(":/new/lingcunwei.png"));
    ui->actiontui->setIcon(QIcon(":/new/tuichu.png"));
    ui->action_11->setIcon(QIcon(":/new/dakai.png"));
    ui->actionfuzhi->setIcon(QIcon(":/new/fuzhi.png"));
    ui->actionzhantie->setIcon(QIcon(":/new/zhantie.png"));
    ui->actionjianqie->setIcon(QIcon(":/new/jianqie.png"));
    ui->actionchao->setIcon(QIcon(":/new/chazhao.png"));
    ui->actionhuan->setIcon(QIcon(":/new/tihuan.png"));
    ui->menu_insert->setIcon(QIcon(":/new/charu.png"));
    ui->actionsetfont->setIcon(QIcon(":/new/shezhi.png"));

?三、运行效果

? ? 由于运行效果不便展示(各个功能需要编辑代码进行测试),仅展示程序运行后的主界面。



总结

? ? QT Creator 的函数库很丰富,功能很强大,使用起来很方便。上面仅仅是一个非常简单的例子,希望同学们在开发的过程中能够体会到C++语言的优势。(嘿嘿,比较懒的同学可以私信作者直接获取原project哦)

? ? 同学们如果想利用QT Creator 进行多人开发同一个项目,可以使用SVN、Git等版本控制器。?

? ? 初次编写博客,难免有所疏漏,还望观众老爷谅解,能向笔者提出批评指正,谢谢!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:12:27  更:2021-10-18 17:15:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:29:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码