核心代码如下:这里设置为最大为90个字节,当然也可以设置为文字个数count。
noticeLabel->setVisible(false);
noticeLabel->setStyleSheet("color:red");
noticeLabel->setText(tr("Can only enter 90 bytes"));//注:中文翻译为30个字,英语翻译为90个字符。
inputText->setAcceptRichText(false); //去掉复制文字的颜色字体等属性
inputText->moveCursor(QTextCursor::Start); //不加这个在输入文字之前复制字体大小可能不对,会受复制内容影响,原因未知。
inputText->setStyleSheet("background-color:palette(button);");
inputText->setPlaceholderText(tr("Enter text, up to 90 bytes"));//注:中文翻译为30个字,英语翻译为90个字符。
connect(inputText,&QTextEdit::textChanged,this,[=]{
//qDebug()<<"words = "<<inputText->toPlainText().toLocal8Bit().length();
if(inputText->toPlainText().toLocal8Bit().length() > 90) {
noticeLabel->setVisible(true);
QString textString = inputText->toPlainText().toLocal8Bit().mid(0,90);//一个中文三个字节
inputText->setText(textString);//设置文本内容为限制字节内的内容
QTextCursor textCursor = inputText->textCursor();
textCursor.movePosition(QTextCursor::End);//光标移动到末尾
inputText->setTextCursor(textCursor);
} else if (inputText->toPlainText().toLocal8Bit().length() == 90) {
noticeLabel->setVisible(true);
} else {
noticeLabel->setVisible(false);
}
});
注:这里还是会有一些问题,用90个字节去判断,一个汉字是3个字节,但是一个标点是1个字节,也就意味着当输入中文时可能出现91、92个字节的情况。这时,mid会取0~90字节的内容,如果最后一个是汉字,那么最后一个汉字依然会被取用,这样就会导致内容一直是91/92,就会陷入无线循环。所以之后我还是改为了用直接判断个数的方法,暂时不对汉字和英文等字符进行区别处理。不过这里应该是可以优化的。
效果如下:
核心代码:
inputText = new QTextEdit(); //用户输入文字
QLabel *noticeLabel = new QLabel(inputText);
QVBoxLayout *noticeLayout = new QVBoxLayout();
inputText->setLayout(noticeLayout);
inputText->setContextMenuPolicy(Qt::NoContextMenu); //不要右击菜单,右击菜单导致选择状态的清除不好实现
inputText->setFixedHeight(84);
inputText->setFontPointSize(14);
inputText->setAcceptRichText(false); //去掉复制文字的颜色字体等属性
inputText->moveCursor(QTextCursor::Start); //不加这个在输入文字之前复制字体大小可能不对,会受复制内容影响。
inputText->setStyleSheet("background-color:palette(button);");
inputText->setPlaceholderText(tr("Enter text, up to 30 characters"));
QVBoxLayout *noticeLayout2 = new QVBoxLayout();
QHBoxLayout *noticeLayout3 = new QHBoxLayout();
noticeLayout->addLayout(noticeLayout2);
noticeLayout->addStretch();
noticeLayout->addLayout(noticeLayout3);
noticeLayout3->addStretch();
noticeLayout3->addWidget(noticeLabel);
noticeLabel->setStyleSheet("background-color:rgba(0,0,0,0)");
noticeLabel->setText("0/30");
noticeLabel->setFixedSize(38,25);
noticeLabel->setAlignment(Qt::AlignRight);
connect(inputText,&QTextEdit::textChanged,this,[=]{
if(inputText->toPlainText().count() > 30) {
noticeLabel->setText("30/30");
QString textString = inputText->toPlainText().mid(0,30);
inputText->setText(textString);
//设置光标在末尾
QTextCursor textCursor = inputText->textCursor();
textCursor.movePosition(QTextCursor::End);
inputText->setTextCursor(textCursor);
} else if (inputText->toPlainText().count() == 30) {
noticeLabel->setText("30/30");
} else {
noticeLabel->setText(QString("%1/30").arg(inputText->toPlainText().count()));
}
qScreensaverDefaultSetting->set(MYTEXT_KEY,inputText->toPlainText());
});
这种设置光标在末尾还是不行的,在中间添加文字到达上限时,光标会移到末尾,所以修改一下:
connect(inputText,&QTextEdit::textChanged, this, [=]{
if(inputText->toPlainText().count() > 30) {
noticeLabel->setText("30/30");
int length = inputText->toPlainText().count();
QString text = inputText->toPlainText();
int position = inputText->textCursor().position(); //输入后光标原应该在的位置
QTextCursor text_cursor = inputText->textCursor();
text.remove(position - (length - 30), length - 30);//去掉多余的文字
inputText->setText(text);
text_cursor.setPosition(position - (length - 30));//光标移到正确的位置
inputText->setTextCursor(text_cursor);
} else if (inputText->toPlainText().count() == 30) {
noticeLabel->setText("30/30");
} else {
noticeLabel->setText(QString("%1/30").arg(inputText->toPlainText().count()));
}
qScreensaverDefaultSetting->set(MYTEXT_KEY, inputText->toPlainText());
});
输入字符显示放在右下角,一开始想用网格布局做,但是没调好,还是直接用水平+垂直布局做的:
简介图:
QLineEdit限制字数:
inputText->setText(inputText->text().mid(0, 30));
不过使用setMaxLength()应该更加合适,因为每次setText会把鼠标光标移到末尾:
inputText->setMaxLength(30);