傻瓜式网站开发,厦门做网站哪家公司好,长沙网站建设接单,海盐建设局网站写作天下简介为作家们创造世界而诞生#xff0c;执云作笔#xff0c;诉尽平生意。集简约UI与人性化AI于一体的码字工具#xff0c;无论是小说、作文、日记、报告#xff0c;都能轻松驾驭。QQ交流群#xff1a;705849222特点已有功能#xff1a;自由的目录#xff1a;自动…写作天下简介为作家们创造世界而诞生执云作笔诉尽平生意。集简约UI与人性化AI于一体的码字工具无论是小说、作文、日记、报告都能轻松驾驭。QQ交流群705849222特点已有功能自由的目录自动序号导入导出一体化界面全局自定义主题输入动画独创文字平滑输入效果、光标平滑移动智能引号增删移动全在一键之间智能空格缩进、标点、移动光标融为一体智能回车双引号内回车、自动添加句末标点、自动缩进自动标点语气词后面自动加上标点符号同音词覆盖选词错误无需删除直接覆盖旧内容自动分段换行/排版时过长段落自动在合适的地方分段自动提示输入时自动提示同义词、相关词、常用句随机取名最轻便的取名方式要啥来啥一键排版全自动未来功能(近期繁忙无力开发)大纲列表章节细纲名片注释名字高亮综合搜索全书替换右下角通知卡片自定义主题自定义快捷键小黑屋云同步排行榜拼字房间章节分享“求评价”广场主角背包快捷键ctrl ←/→ 按词语移动alt ←/→ 按句子移动ctrl alt ←/→ 按段落移动ctrl shift ↑/↓ 扩大/缩小选择ctrl/alt ↑/↓ 屏幕滚动alt更快空格键 智能空格引号键 智能引号回车键 智能回车Tab键 句子补全光标跳过ctrlT 一键排版ctrlD 句内同音词替换(不必连续)ctrlF 章内文字搜索ctrlP 全局综合搜索更多快捷键请等待后期加入(或将支持自定义快捷键)技术特点开发环境C/Qt5.11.3Qt Creator运行环境Windows、Android1、标点AI虽然是简单暴力的枚举(都是自己遇到的)但是有特判了上千种情况也不容易吧……若是人物语言描写还能根据人物的表情动作神态来分析情感程度进一步提高准确度。手动判断故覆盖不全不过在一定情况下枚举简单易用是为上上之选还有各种常用按键的自动化操作极大程度上增加效率/*** 小说语气识别的AI类*/class NovelAIBase{/*...略了一些方法...*/void operatorSmartSpace(); // 智能空格按下空格触发void operatorSmartEnter(); // 智能回车按下回车触发void operatorSmartQuotes(); // 智能引号按下引号触发void operatorSmartBackspace(); // 智能删除按下删除触发bool operatorAutoPunc(); // 自动标点语气词自动触发bool operatorSentFinish(); // 句末标点增加或转化成结尾void operatorSmartQuotes2(int left, int right); // 智能引号仅在选中文本的情况下调用virtual int getWordCount(QString str); // 字数统计交给 NovelAIQString getPunc(QString para/*段落*/, int pos/*光标*/); // ☆核心取标点(句子)QString getPunc(/*QString fullText, int pos*/); // 这个是全部文本中的某一部分QString getPunc(int pos); // 全部文本特定位置的标点QString getPunc2(int pos); // 把改成。QString getPunc2(); // 把改成。int getDescTone(QString sent); // 句子语气标点影响语气导向QString getTalkTone(QString sent, QString sent2, int tone, QString left1, QString left2);void updateCursorChars(); // 修改光标附近的字符bool canDeletePairPunc(); // 是否能够删除成对文本(能删就删)bool isCursorInQuote(QString text, int pos); // 是否在引号里面virtual void moveCursor(int x) 0; // 移动光标virtual void insertText(int pos, QString text) 0; // 插入文本virtual void insertText(QString text) 0; // 插入文本virtual void deleteText(int start, int end) 0; // 删除文本// bool isNextLang(); // 是否是后一句话(双引号前面多的是逗号)bool isSentPunc(QString str); // 是否为句末标点(不包含引号和特殊字符不包括逗号)bool isSentSplitPunc(QString str); // 是否为句子分割标点(包含逗号)bool isSentSplit(QString str); // 是否为句子分割符(各类标点包括逗号)bool isASCIIPunc(QString str); // 是否为英文标点(不包含引号和特殊字符)bool isBlankChar(QString str); // 是否为空白符bool isBlankChar2(QString str); // 是否为换行之外的空白符bool isBlankString(QString str); // 是否为空白字符串bool isSymPairLeft(QString str); // 是否为对称标点左边的bool isSymPairRight(QString str); // 是否为对称标点右边的QString getSymPairLeftByRight(QString str); // 根据右边括号获取左边的括号QString getSymPairRightByLeft(QString str); // 根据右边括号获取左边的括号QString getCursorFrontSent(); // 获取当前面的句子QString getCurrentChar(int x); // 获取当前位置的附近汉字bool isQuoteColon(QString str); // 汉字后面是否需要加标点protected:QString _text, _pre_text; // 文本int _pos, _pre_pos, _dif; // 光标位置和字数差QString _left1, _left2, _left3, _right1, _right2; // 光标附近的文本bool isInQuotes; // 是否在引号里面(用来判断是否为语言或者描述)private:QString _shuo_blacklists, _dao_whitelists, _wen_blacklists; // “说”黑名单、“道”白名单、“问”黑名单QString _symbol_pair_lefts, _symbol_pair_rights; // 成对符号左边/右边QString _quote_no_colon, _quantifiers; // 引号前面没有冒号QString _sent_puncs, _sent_split, _sent_split_puncs, _blank_chars; // 句末标点、句子分割符、空白符QString _auto_punc_whitelists; // 自动标点白名单};子类为NovelAI再下一个子类 NovelEditor 使用到了多继承同时继承 QTextEdit 与 NovelAI。其实设计得不是很好AI 类需要大量调用 Edit 的方法于是加了许多虚函数将三个类紧紧耦合到一起(不过关系不大本来就是怕一个文件代码太长而分开的)。2、仿IDE思路当今所谓的写作软件单论写作方面其实和一个记事本没多少差别无非多了目录与自动缩进以及简单的自动保存等。其一些亮点比如强制写作的小黑屋、多人竞争的在线拼字都无法从“码字”本身来帮助作者达到更高效的办公这些附加的功能甚至会让作者分心无法好好静心创作。写作天下定位一款单纯的“文学创作”编辑器主打从“写作”本身提高效率弱化与文字无关的功能。或许后期将会添加小黑屋、拼字等但绝不会将这些作为主要功能。备注近期繁忙无力开发所以只是“思路”一些功能增强的编辑功能自动提示面向对象写作名片系统文字高亮(名片高亮)高度个性化设置(功能细节、快捷键、主题等)追求自动的编辑器一句话能自动的绝不手动为了实现更加人性化的功能程序中使用了大量的算法。比如括号匹配功能输入左括号时自动添加右括号、删除键删除成对的符号这里使用数据结构中的栈判断光标前后各自左右括号的数量入栈出栈来判断是否需要添加/删除而不仅仅依靠光标前一个字符。还有光标移动、在标点前面换行、在语言描写内回车自动插入前后引号、修改引号前面的逗号与冒号等一个按键多种功能。轻松提示经过多种方案的性能测试选取了速度最快、运行最稳定的方式。以下为输入文字后自动提示算法/*** 某个句子的某个位置处进行搜索* param sent 欲搜索的完整句子(短句不包含标点)* param cursor 光标在句子中的相对位置* return 是否找到*/bool Lexicons::surroundSearch(QString sent, int cursor){int len sent.length();search_result.clear();match_sentence false;bool find false;matched_key ;int start_pos 0;QString l1 , l2 , l4 ;if (cursor 1)l1 sent.mid(cursor-1, 1);if (cursor 2)l2 sent.mid(cursor-2, 2);if (cursor 4)l4 sent.mid(cursor-4, 4);if (random_inited){// 随机种类列表if (((matched_key l2) 随机)|| ((matched_key l2) 取名)|| ((matched_key l4) 随机取名))if (searchRandom(随机取名)){matched_case COMPLETER_CONTENT_RAND_LIST;return true;}// 姓氏if (surname_inited (((matched_key l1) 姓)|| ((matched_key l2) 姓氏)))if (searchRandom(姓氏)){matched_case COMPLETER_CONTENT_SURN;return true;}// 人名if (name_inited (((matched_key l2) 人名)|| ((matched_key l2) 名字)))if (searchRandom(人名)){matched_case COMPLETER_CONTENT_NAME;return true;}// 随机列表for (QString s : random_sort_list){if (cursor s.length() sent.mid(cursor-s.length(), s.length()) s isFileExist(lexicon_dir random/ s .txt)){matched_key s;matched_case COMPLETER_CONTENT_RAND;searchRandom(s);return true;}}}// 搜索4个字if (!find){start_pos 0; // 开始搜索的位置if (start_pos cursor-4) start_pos cursor-4;for (int i start_pos; i len-4 i cursor; i){if (search(sent.mid(i, 4), true)){find true;matched_key sent.mid(i, 4);break;}}}// 搜索三个字if (!find){start_pos 0;if (start_pos cursor-3) start_pos cursor-3;for (int i start_pos; i len-3 i cursor; i)if (search(sent.mid(i, 3), true)){find true;matched_key sent.mid(i, 3);break;}}// 搜索两个字if (!find){start_pos 0;if (start_pos cursor-2) start_pos cursor-2;for (int i start_pos; i len-2 i cursor; i)if (search(sent.mid(i, 2), true)){find true;matched_key sent.mid(i, 2);break;}}//qDebug() surround search: matched_key result: search_result;search_last sent;matched_case COMPLETER_CONTENT_WORD;return find;}/*** 在词库中搜索某一个词语* param key 欲搜索的词语* param add 是否为添加模式。如果不是则先清空已经找到的列表* return 是否有搜索结果*/bool Lexicons::search(QString key, bool add){if (key.isEmpty()) return false;/* // 上次搜索的缓冲区但是没必要了因为每次surroundSearch的时候* // 都把上次的搜索结果清空了key还在但是result没了if (key search_last){return true;}*/if (!add) search_result.clear();bool find false;int key_len key.length();if (synonym_inited){QStringList synonym_list;int pos 0;while (1){//pos synonym_text.indexOf(key, pos);pos synonym_text.indexOf(QRegExp(\\bkey\\b), pos);if (pos -1) break;int left synonym_text.lastIndexOf(\n, pos)1;int right synonym_text.indexOf(\n, pos);if (right -1) right synonym_text.length();QString para synonym_text.mid(left, right-left);QStringList list para.split( , QString::SkipEmptyParts);// TODO 后期将改成 QListsynonym_list.append(list);pos key_len;find true;}if (synonym_list.size() 0 shouldRandom()){if (shouldRandom()){std::random_shuffle(synonym_list.begin(), synonym_list.end());}search_result.append(synonym_list);}}if (related_inited){QStringList related_list;int pos 0;while (1){pos related_text.indexOf(QRegExp(\\bkey\\b), pos);if (pos -1) break; // 找不到了if (pos 0 related_text.mid(pos-1, 1) {) // 是标题{int left related_text.indexOf([, pos)1;int right related_text.indexOf(], pos);if (right left-1) // 出现了错误{pos left1;continue;}if (right -1) right related_text.length();QString para related_text.mid(left, right-left);QStringList list para.split( , QString::SkipEmptyParts);// TODO 后期将改成 QListrelated_list.append(list);pos right;}else // 是内容{// 如果是本程序标准格式int left related_text.lastIndexOf([, pos)1;int right related_text.indexOf(], pos);// 如果只是一段一段分开的int left_n related_text.lastIndexOf(\n, pos)1;if (left_n left){left left_n;right related_text.indexOf(\n, pos);}if (right -1) right related_text.length();QString para related_text.mid(left, right-left);QStringList list para.split( , QString::SkipEmptyParts);// TODO 后期将改成 QListrelated_list.append(list);pos right;}find true;}if (related_list.size() 0){if (shouldRandom()){std::random_shuffle(related_list.begin(), related_list.end());}search_result.append(related_list);}}if (sentence_inited find){if (sentence_text.indexOf(key) -1){match_sentence true;search_result.append(--);}}//qDebug() search: key result: search_result;return find;}/*** 通过一个词语来获取应该显示的随机取名提示列表* param key 欲搜索的词语* return 是否找到结果*/bool Lexicons::searchRandom(QString key){// 随机取名列表 if (key 随机取名 || key 随机 || key 取名){for (QString s : random_sort_list)search_result.append(s);std::random_shuffle(search_result.begin(), search_result.end());return true;}// 随机取名具体 for (int i 0; i random_sort_list.size(); i)if (random_sort_list.at(i) key){QStringList list random_text_list.at(i).split( , QString::SkipEmptyParts);search_result list;std::random_shuffle(search_result.begin(), search_result.end());search_result search_result.mid(0, 100);return true;}return false;}/*** 搜索后返回结果* return 搜索结果*/QStringList Lexicons::getResult(){return search_result;}3、平滑输入创作或是为了宁静的内心或是为了美好的生活终是需要解放内心的压抑。而写作天下的输入动画与平滑光标为了打造愉悦的创作环境可谓是呕心沥血。动画算法输入动画输入动画中每一个字符都是一个Label对象设置文字颜色为对应字符然后使用一个动画管理器进行统一管理开放管理器的API给编辑器编辑文字的同时通过管理器调整所有文字的动画便不会出现冲突的情况。难点在要将每个Label和对应文字连在一起尤其是支持实时修改。看了其他相同功能的开源项目大多只支持英文并且是监听到文字输入后才开始动画等动画结束再上屏无法在输入后立即删除或者修改非常影响效率。/*** 输入动画管理器类*/class EditorInputManager : public QObject{Q_OBJECTpublic:EditorInputManager();void setEditor(QTextEdit* edit); // 设置开启动画对应的编辑器void setColor(QColor color); // 设置全文颜色void textChanged(int old_position, int diff); // 文字改变时调整动画控件void updateRect(int range_start, int rande_end); // 更新动画控件的位置void addInputAnimation(QPoint point, QString str, int position, int delay, int duration); // 添加一个文字动画void addInputAnimation(QPoint point, QString str, int position, int delay, int duration, QColor color); // 添加一个带有不同颜色的文字动画void updateTextColor(int current_position); // 修改全文颜色同时修改正在动画的颜色public slots:void aniFinished(int position, EditorInputCharactor *); // 动画结束传参文字位置private:QTextEdit* _edit; // 编辑器QColor font_color; // 全文颜色QList ani_list; // 动画控件列表};/*** 输入动画的某一个字符实体存储动画信息、光标位置、光标坐标、光标文字等*/class EditorInputCharactor : public QLabel{Q_OBJECTQ_PROPERTY(int fontsize READ getFontSize WRITE setFontSize RESET resetFontSize)public:EditorInputCharactor(QWidget* parent, QPoint point, QString str, int position, QFont font, int delay 0, int duration 200);int getPosition(); // 获取动画的文字位置更新位置、动画结束文字变回原色时要用到void changePosition(int x); // 修改动画的位置void updateRect(QPoint point); // 更新控件坐标// 字体动画接口void setFontSize(int x);int getFontSize();void resetFontSize();signals:void aniFinished(int position, EditorInputCharactor* charactor); // 动画结束private:QPoint point; // 坐标QString str;int position; // 文字位置int duration; // 动画时长同时输入的不同位置的文字时长不一样QPropertyAnimation *ani; // 动画对象int origin_position; // 一开始的位置int font_size; // 文字大小动画属性int font_size_l;};平滑光标平滑光标添加一个矩形控件为光标样式每次改变时存储其坐标然后借助动画移动控件。其实还简单但难点在要好好控制什么时候才开始动画不然光标会乱飘或者闪动看起来效果很差。最大的难点在于与功能“光标行固定”以及“底部光标固定”有很大的冲突还有每次修改文字时(这是自定义事件经常使用QTextEdit.setText()方法才会出现的问题)需要大大约束光标动画的时机。4、MVD目录结构Qt标准 QListView 的MVD模型一开始以为很难刚走来发现其实就是重写几个方法。这里使用的 MVD似乎与标准的不太一样看下去就知道了。Model由于写作天下的目录比较复杂所以专门写了一个类NovelDirMData来存放多个NovelDirItem的信息。此处 Model 用到了多继承以及友元。(其实这个模型已经变了味了)class NovelDirModel : public QAbstractListModel, public NovelDirMData{/*...其余代码略...*/QVariant data(const QModelIndex index, int role Qt::DisplayRole) const{// 不需要 index 的 dataif (role Qt::UserRoleDRole_ROLL_COUNT){return roll_subs.size();}else if (role Qt::UserRoleDRole_CR_COUNT){return cr_list.size();}else if (role Qt::UserRoleDRole_ROLL_NAMES){return roll_names;}// 判断 indexif ((!index.isValid()) || (index.row() cr_list.size()))return QVariant();NovelDirItem item cr_list.at(index.row());if (role Qt::UserRoleDRole_CHP_NAME){return item.getName(); // 章节名}else if (role Qt::UserRoleDRole_CHP_NUM){return item.getNumber(); // 序号}else if (role Qt::UserRoleDRole_CHP_NUM_CN){return item.getNumber_cn(); // 序号}else if (role Qt::UserRoleDRole_CHP_ROLLINDEX){return item.getRollIndex(); // 序号}else if (role Qt::UserRoleDRole_CHP_CHPTINDEX){return item.getChptIndex(); // 序号}else if (role Qt::UserRoleDRole_CHP_DETAIL){return item.getDetail(); // 细纲}else if (role Qt::UserRoleDRole_CHP_OPENING){return item.isOpening(); // 是否编辑中}else if (role Qt::UserRoleDRole_CHP_ISROLL){return item.isRoll(); // 是否为分卷}else if (role Qt::UserRoleDRole_CHP_ISHIDE){return item.isHide(); // 是否隐藏}else if (role Qt::UserRoleDRole_CHP_STEMP){return item.getS_temp(); // 双击编辑出错后恢复原来的文本}else if (role Qt::UserRoleDRole_ROLL_SUBS){int rIndex item.getRollIndex();return roll_subs[rIndex]; // 分卷章数量}else if (role Qt::UserRoleDRole_ROLL_COUNT){return roll_subs.size();}else if (role Qt::UserRoleDRole_CR_COUNT){return cr_list.size();}else if (role Qt::UserRoleDRole_CHP_FULLNAME){return item.getFullChapterName();}else if (role Qt::UserRoleDRole_RC_ANIMATING){return item.isAnimating();}else if (role Qt::UserRoleDRole_ROLL_NAMES){return roll_names;}else if (role Qt::UserRoleDRole_RC_SELECTING){return item.isSelecting();}return QVariant();}// 重写 flags 和 setData 使 Model 可双击编辑Qt::ItemFlags flags(const QModelIndex index) const{Qt::ItemFlags flags QAbstractItemModel::flags(index);//if (index.row() 0 us-one_click) // 作品相关卷名不允许更改//flags | Qt::ItemIsEditable;if (index.row() 0)flags | Qt::ItemIsEditable;return flags;}bool setData(const QModelIndex index, const QVariant value, int role){if (!index.isValid()) return false;NovelDirItem item cr_list.at(index.row());if (role Qt::EditRole) // 修改章节名{QString old_name item.getName();bool isNew false;if (canRegExp(old_name, 新[章卷]\\d)) // 分卷是聚集焦点用isNew true;bool rst tryChangeName(index.row(), value.toString());if (/*isNew */rst) // 重命名成功{if (isNew) // 如果是新建的emit signalOpenChapter(index.row());else // 否则就是重命名修改已经打开的旧名字标签页emit signalChangeFullName(novel_name, value.toString());}return rst;}else if (role Qt::UserRoleDRole_CHP_STEMP){cr_list[index.row()].setS_temp(value.toString());}else if (role Qt::UserRoleDRole_CHP_FULLNAME){cr_list[index.row()].setFullChapterName(value.toString());deb(value.toString(), model.setFullChapterName);}return true;}}View这里重写的方法有点多……就放一个设置Model和Delegate的。不是很标准因为为了方便把应该解耦的Model和Delegate都声明为成员变量了。// 设置 delegatenovel_dir_delegate new NovelDirDelegate(this);setItemDelegate(novel_dir_delegate);// 设置 modelnovel_dir_model new NovelDirModel(this);setModel(novel_dir_model);Delegate因为用到了作品设置有用户自定义的完全不同的目录结构所以和Model一样使用了多继承。有三大特色用户自定义文字显示例如阿拉伯数字自动排序、不显示分卷等圆形显示效果不知道该怎么描述……至少要比默认的蓝色选中效果好看吧支持全局主题色/点缀色实时修改/*** 目录列表代理类*/class NovelDirDelegate : public QItemDelegate, public NovelDirSettings{/* ... 略了一些 ... */QString getItemText(const QModelIndex index) const{ /*...获取章节序号略...*/}void paint(QPainter *painter, const QStyleOptionViewItem option, const QModelIndex index) const{QStyleOptionViewItem op(option);op.palette.setColor(QPalette::Highlight, us-getOpacityColor(us-accent_color, 128));painter-save();// 获取文字QString text getItemText(index);int deviate DIR_DEVIATE; // 初始偏移位置int subs -1; // 分卷数量章节为-1if (index.data(Qt::UserRoleDRole_CHP_ISROLL).toBool()) // 是分卷画数字{subs index.data(Qt::UserRoleDRole_ROLL_SUBS).toInt();}else // 是章节{if (isNoRoll() index.data(Qt::UserRoleDRole_CHP_NUM).toInt() 0) // 不显示分卷 且 是正文则取消缩进;elsedeviate DIR_DEVIATE_ADD; // 增加章节的缩进}// 获取文字区域并绘制QFontMetrics fm(painter-font());QRect text_rect QRect(op.rect.topLeft()QPoint(deviate,(op.decorationSize.height()us-mainwin_sidebar_spacing*2-fm.height())/2),QSize(fm.width(text),fm.height()));if (!us-round_view)drawBackground(painter, op, index); // 画选中的颜色的(不加这行的话就是透明选中)// 先绘制背景if (!index.data(Qt::UserRoleDRole_RC_ANIMATING).toBool()) // 不是在动画中(动画时不显示文字即背景透明){// 绘制选中状态的纸片形状背景if (us-round_view (option.state QStyle::State_Selected)){int text_padding text_rect.height()/2-1;QColor bg_color us-getOpacityColor(us-accent_color, 128);QRect round_rect(text_rect.left()-text_padding, text_rect.top()-3, text_rect.width()text_padding*2, text_rect.height()6);painter-setRenderHint(QPainter::Antialiasing);QPen pen(bg_color, Qt::NoPen);painter-setPen(pen);QPainterPath path;int radius round_rect.height()/2-1;path.addRoundedRect(round_rect, radius, radius);painter-fillPath(path, bg_color);painter-drawPath(path);painter-setRenderHint(QPainter::Antialiasing, false);}// 绘制文字if (isNoRoll() subs 0) // 不使用分卷并且刚好是分卷则使用灰色弱化分卷存在感{painter-setPen(QColor(128, 128, 128));}elsepainter-setPen(QColor(0, 0, 0));painter-drawText(text_rect, text);// 画左边的小标记if (subs 0) // 是分卷(章节默认 -1){}else // 是章节绘制打开状态{if (index.data(Qt::UserRoleDRole_CHP_OPENING).toBool()) // 打开状态中画右边的小点{QRect state_rect QRect(op.rect.topLeft()QPoint(0,1),QSize(1,op.rect.height()-2));painter-setPen(QPen(QColor(us-accent_color), Qt::SolidLine));painter-setBrush(QBrush(QColor(us-accent_color), Qt::SolidPattern));painter-drawRect(state_rect);}}// 画右边的小标记分卷数量if (subs 0) // 是分卷(章节默认 -1){if (subs 0) // 没有章节灰色的数字{painter-setPen(QColor(128, 128, 128));}else // 章节黑偏灰色的{painter-setPen(QColor(64, 64, 64));}QString subs_text QString(%1).arg(subs);QRect display_rect2 QRect(op.rect.topRight()-QPoint(fm.width(subs_text)10,-3),QSize(fm.width(subs_text),fm.height()));painter-drawText(display_rect2, subs_text);}}// drawFocus(painter, option, displayRect); // 画选区虚线drawFocus(painter, op, QRect(0, 0, 0, 0));painter-restore();}QSize sizeHint(const QStyleOptionViewItem option, const QModelIndex index) const{Q_UNUSED(index);//QSize size option.rect.size(); // 这个是整个QListView的矩形……QSize size option.decorationSize;size.setHeight(size.height()us-mainwin_sidebar_spacing*2);return size;//QItemDelegate::sizeHint(o2, index);}/* 编辑框修改名字 */QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem option, const QModelIndexindex) const{Q_UNUSED(option);Q_UNUSED(index);QLineEdit* edit new QLineEdit(parent);edit-setAcceptDrops(false);QString style ;//background-color:us-getColorString(us-accent_color);;if (us-round_view){QString text getItemText(index);QFontMetrics fm(edit-font());int r fm.height()/2;QString rs QString(%1).arg(r);style border:1px;border-radius:rspx; padding-left: rspx;;}elsestyle border:none;;edit-setStyleSheet(style);QPalette palette edit-palette();if (us-editor_font_color.alpha() 0)palette.setColor(QPalette::Text, us-editor_font_color);palette.setColor(QPalette::Base, us-accent_color/*editor_bg_color*/);if (us-editor_font_selection.alpha() 0)palette.setColor(QPalette::HighlightedText, us-editor_font_selection);palette.setColor(QPalette::Highlight, us-editor_bg_selection);edit-setPalette(palette);return edit;}void setEditorData(QWidget *editor, const QModelIndex index) const{QString name index.data(Qt::UserRoleDRole_CHP_NAME).toString();if (index.data(Qt::UserRoleDRole_CHP_STEMP).toString() ! )name index.data(Qt::UserRoleDRole_CHP_STEMP).toString();QLineEdit* edit static_cast(editor);// renameEdit edit;edit-setText(name);}void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex index) const{QLineEdit* edit static_cast(editor);QString str edit-text();//closeEditor(edit, QAbstractItemDelegate::NoHint);if (model-setData(index, str))model-setData(index, str, Qt::UserRoleDRole_CHP_STEMP);elsemodel-setData(index, str, Qt::UserRoleDRole_CHP_STEMP);}void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem option, const QModelIndex index) const{Q_UNUSED(index);int deviate DIR_DEVIATE-2;if (!(index.data(Qt::UserRoleDRole_CHP_ISROLL).toBool()))deviate DIR_DEVIATE_ADD;if (us-round_view){QString text getItemText(index);QFontMetrics fm(editor-font());int delta fm.height()/2;deviate - delta;}QRect rect option.rect;rect.setLeft(rect.left()deviate);editor-setGeometry(rect);}QLineEdit* getEditor(){return rename_edit;}private :QLineEdit* rename_edit;};使用这个代理后发现效果还是挺好看的比原先不知道好了多少。