我想用qtextedit写一个markdown编辑器程序。在typora中,像“#”、“*”这样的单词只有在光标位于它们上面时才会显示。我希望在我自己的程序中实现这个功能。我是qt新手。那么,有什么简单的方法可以做到这一点吗?提前谢谢。
发布于 2021-05-04 21:34:17
不幸的是,QTextEdit不支持:hover伪类选择器。但您可以跟踪鼠标位置并应用样式来实现扰流效果。
///////////////////// textedit.h
#ifndef TEXTEDIT_H
#define TEXTEDIT_H
#include <QTextEdit>
class TextEdit : public QTextEdit
{
Q_OBJECT
public:
explicit TextEdit(QWidget *parent = nullptr);
void initSpoilers();
protected:
void mouseMoveEvent(QMouseEvent *event);
void leaveSpoiler();
void enterSpoiler(int index);
QList<QPair<int,int> > mSpoilers;
QTextCharFormat mSpoilerFormat;
int mSpoilerIndex;
};
#endif // TEXTEDIT_H
///////////////////// textedit.cpp
#include "textedit.h"
#include <QMouseEvent>
#include <QTextCursor>
#include <QDebug>
#include <QTextDocument>
#include <QTextBlock>
TextEdit::TextEdit(QWidget *parent) : QTextEdit(parent), mSpoilerIndex(-1)
{
}
void TextEdit::initSpoilers()
{
QTextDocument* doc = document();
mSpoilers.clear();
for (QTextBlock block = doc->begin(); block != doc->end(); block = block.next()) {
for(QTextBlock::iterator it = block.begin(); it != block.end(); it++) {
QTextFragment fragment = it.fragment();
QTextCharFormat format = fragment.charFormat();
if (format.background().style() == Qt::NoBrush) {
continue;
}
int head = fragment.position();
int tail = fragment.position() + fragment.length();
mSpoilers.append(QPair<int,int>(head, tail));
mSpoilerFormat = format;
}
}
}
void TextEdit::enterSpoiler(int index)
{
QTextCursor cursor(document());
cursor.setPosition(mSpoilers[index].first);
cursor.setPosition(mSpoilers[index].second, QTextCursor::KeepAnchor);
QTextCharFormat format;
format.setForeground(QBrush(Qt::black));
cursor.setCharFormat(format);
mSpoilerIndex = index;
}
void TextEdit::leaveSpoiler()
{
int index = mSpoilerIndex;
QTextCursor cursor(document());
cursor.setPosition(mSpoilers[index].first);
cursor.setPosition(mSpoilers[index].second, QTextCursor::KeepAnchor);
cursor.setCharFormat(mSpoilerFormat);
mSpoilerIndex = -1;
}
void TextEdit::mouseMoveEvent(QMouseEvent *event)
{
QTextCursor cursor = cursorForPosition(event->pos());
int pos = cursor.position();
int spoilerIndex = -1;
for(int i=0;i<mSpoilers.size();i++) {
const QPair<int,int>& spoiler = mSpoilers[i];
if (spoiler.first < pos && pos < spoiler.second) {
spoilerIndex = i;
}
}
if (spoilerIndex > -1 && mSpoilerIndex < 0) {
enterSpoiler(spoilerIndex);
} else if (spoilerIndex < 0 && mSpoilerIndex > -1) {
leaveSpoiler();
}
}
///////////////////// main.cpp
#include <QApplication>
#include "textedit.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TextEdit edit;
edit.setHtml("<html>"
"<head>"
" <style>"
" .spoiler {color: gray; background-color: gray;}"
" </style>"
"</head>"
"<body>"
" <p>"
" Lorem ipsum dolor sit amet consectetur adipisicing elit. Culpa facere error"
" optio, modi, assumenda accusantium tempore hic <span class=\"spoiler\">iure"
" reprehenderit repudiandae</span> molestiae placeat vel consequatur rerum nisi"
" architecto inventore, adipisci ex?"
" </p>"
" <p>"
" Dicta modi accusantium quo molestiae, inventore possimus quaerat explicabo"
" itaque quidem quia minima reprehenderit beatae, <span class=\"spoiler\">"
" architecto quae tempore dolores</span>. Possimus numquam"
" delectus nisi deserunt dolorem rerum voluptatem doloremque! Odit, eos."
" </p>"
" <p>"
" Doloremque, amet totam! <span class=\"spoiler\">Ab tempore possimus"
" accusamus</span> blanditiis accusantium quibusdam assumenda quo iure laborum,"
" minima cupiditate impedit corrupti vero provident aspernatur quod aliquam?"
" Error eius odio aliquid est vel quasi."
" </p>"
"</body>"
"</html>");
edit.initSpoilers();
edit.show();
return a.exec();
}https://stackoverflow.com/questions/67378482
复制相似问题