效果示例:
MTextEdit.h
//********************************************************
/// @brief 多行文本框,允许设置最大字符数
/// @author y974183789@gmail.com
/// @date 2021/9/1
/// @note
/// @version 1.0.0
//********************************************************
#pragma once
#include <QtCore/qnamespace.h>
#include <QtWidgets/QTextEdit>
#include <QtCore/QtGlobal>
class MTextEditPrivate;
class MTextEdit : public QTextEdit {
Q_OBJECT
Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength)
public:
MTextEdit(QWidget *parent = Q_NULLPTR);
~MTextEdit();
int maxLength() const;
void setMaxLength(int maxLength);
protected:
void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(MTextEdit);
private:
MTextEditPrivate* d_ptr;
};
MTextEdit.cpp
//********************************************************
/// @brief 多行文本框,允许设置最大字符数
/// @author y974183789@gmail.com
/// @date 2021/9/1
/// @note
/// @version 1.0.0
//********************************************************
#include "MTextEdit.h"
#include <QtWidgets/QLabel>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QSpacerItem>
#include <QtGui/QResizeEvent>
/*!
* \internal
*
* MTextEdit 私有类
*/
class MTextEditPrivate {
Q_DECLARE_PUBLIC(MTextEdit)
public:
MTextEditPrivate(MTextEdit *q)
: q_ptr(q)
, maxLength(INT_MAX) {
}
public:
void init();
public:
int maxLength;
private:
bool isCountLabelVisible() const;
private:
MTextEdit* q_ptr;
QLabel* m_pCountLabel;
};
bool MTextEditPrivate::isCountLabelVisible() const {
return maxLength > 0 && INT_MAX > maxLength;
}
void MTextEditPrivate::init() {
Q_Q(MTextEdit);
m_pCountLabel = new QLabel(q);
m_pCountLabel->setObjectName("m_txCountLabel");
m_pCountLabel->setStyleSheet("background-color: transparent;");
m_pCountLabel->setAlignment(Qt::AlignmentFlag::AlignRight | Qt::AlignVCenter);
m_pCountLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
//显示数量标签
m_pCountLabel->setVisible(isCountLabelVisible());
QObject::connect(q, &QTextEdit::textChanged, q, [ q, this ] {
QString content = q->toPlainText();
int contentLength = content.size();
if (contentLength > maxLength) {
QTextCursor cursor = q->textCursor();
int pos = cursor.position();
content.remove(pos - (contentLength - maxLength), contentLength - maxLength);
q->setText(content);
cursor.setPosition(pos - (contentLength - maxLength));
q->setTextCursor(cursor);
contentLength = maxLength;
}
if (Q_NULLPTR != m_pCountLabel && isCountLabelVisible()){
m_pCountLabel->setText(QString("%1/%2").arg(contentLength).arg(maxLength));
m_pCountLabel->setVisible(contentLength > 0);
}
});
}
MTextEdit::MTextEdit(QWidget *parent)
: QTextEdit(parent)
, d_ptr(new MTextEditPrivate(this)) {
d_func()->init();
}
MTextEdit::~MTextEdit() {
}
int MTextEdit::maxLength() const {
Q_D(const MTextEdit);
return d->maxLength;
}
void MTextEdit::setMaxLength(int maxLength) {
Q_D(MTextEdit);
d->maxLength = maxLength;
d->m_pCountLabel->setVisible(d->isCountLabelVisible());
}
void MTextEdit::resizeEvent(QResizeEvent *event) {
QTextEdit::resizeEvent(event);
Q_D(MTextEdit);
if (Q_NULLPTR != d->m_pCountLabel) {
d->m_pCountLabel->setGeometry(0, event->size().height(), event->size().width(), d->m_pCountLabel->size().height());
}
}