2023-05-07  Qt5 bug

Qt5 QPlainTextEditのIME変換色バグ対策

Qt5 QPlainTextEdit 背景色とIME

QPlainTextEdit ExtraSelection を使った場合の背景色を暗い色にした時に IME 変換途中の表示が見えにくくなるバグがあります。
背景色が黒の時は発生しませんが 少し他の色を混ぜると 途端に見えにくい色で表示されます。
これも対処療法ですが 対策可能です。

inputMethodEvent を使ってIME変換途中の文字列を取得する

textedit.h
class TextEdit : public QPlainTextEdit { : 中略 // この2つを使います protected: void inputMethodEvent( QInputMethodEvent* m ); void paintEvent(QPaintEvent* event);
textedit.cpp
void TextEdit::inputMethodEvent( QInputMethodEvent* m ) { #if 0 // デバッグ用 QString str; foreach( QInputMethodEvent::Attribute attr, m->attributes() ) { str.append( QString("[%1,%2-%3,%4]") .arg(attr.type) .arg(attr.start) .arg(attr.length) .arg(attr.value.toString()) ); } qDebug() << __FUNCTION__ << "commitStr=" << m->commitString() << ", preEditStr=" << m->preeditString() << ", start=" << m->replacementStart() << ", length" << m->replacementStart() << " | " << str; #endif QString commitstr = m->commitString(); QString prestr = m->preeditString(); // IMEで漢字が確定されたら if(!commitstr.isEmpty()){ // 漢字文字列を2行名以降に挿入、1行目はIMEから送られる m_ColsMode->ColsInsertWord(commitstr, true); m_imeprestr = ""; m_imeprelen = 0; } // IMEのバグ対応 if(!prestr.isEmpty()){ QList<QInputMethodEvent::Attribute> attrs = m->attributes(); m_imeprestr = prestr; m_imeprelen = 0; int len = 0; for(int i=1; i<attrs.count(); ++i){ len += attrs[i-1].length; if(attrs[i].length==0){ // 自前のpaintEventで反転させる m_imeprelen = len - attrs[i].start; int st = attrs[i].start; if( st > 0){ m_imeprestr = prestr.mid(st); } } // qDebug() << "IME BUG" << i << m_imeprelen << m_imeprestr; // QApplication::inputMethod()->update(Qt::ImCursorRectangle); } } QPlainTextEdit::inputMethodEvent(m); }

取得した変換文字列を使って表示する

textedit.cpp
void TextEdit::paintEvent (QPaintEvent *event) { // 私は全部自前で表示していますが、サンプルは QPlainTextEdit の // painteEvent を呼び出すのが分かりやすいでしょう QPlainTextEdit::paintEvent(event); #if 1 // IMEのバグ対応 if(m_imeprelen > 0){ QFont font = viewport()->font(); QFontMetrics fm(font); int lineheight = fm.height(); QTextCursor cur = textCursor(); QRect curRect = cursorRect(cur); painter.save(); int ww = m_imeprelen * fm.width(QChar('あ')); curRect.setWidth(ww); // IME背景色は文字色にする int rc, gc, bc, ac; m_forecolor.getRgb(&rc,&gc,&bc,&ac); ac = 200; // 少し半透明に加工する QColor transcol(rc,gc,bc,ac); // カレント行のIME変換候補位置にバックを塗る painter.fillRect(curRect, transcol); painter.setPen(m_backcolor); // 背景色を文字色に int yy = curRect.y() + lineheight - 6; // この6の根拠はなし int xx = curRect.x(); painter.drawText(QPointF(xx, yy), m_imeprestr); painter.restore(); } #endif }

unieditor の選択行編集モード中に漢字変換をすると 見にくくなるのをこれで回避しています。

最終更新日 2023-05-13
この記事を共有しませんか?
ブックマーク