2023-05-06  Qt5 bug

Qt5 クリップボードバグ対策

Qt5 Windows10,11 setText bug

Qt5.9.5 + Windows10 では QClipBoard::setText が失敗するバグがあります。
Qt5.12 bugfixed となっていますが嘘です。まだ出ます。Qt5.15 でも出ます。連続して出る場合もありますが 頻度が少ないため原因が分からないのでしょう。

setText bug
// 選択範囲 QString cbtext = cr.selectedText(); QClipboard* cb = QApplication::clipboard(); cb->setText(cbtext); // クリップボードに格納

QtCreator 内で実行すると
Call OleInitialize to enable clipboard together with FLTK libraries
とエラーメッセージが表示されています。

エラーメッセージを取得できないか?

対処療法になりますが Qt Message をキャッチする関数を使います。

メッセージハンドラを定義する
// この変数に、エラー時はメッセージが入るようにする QString qtMessagebuf; // Qt Message をキャッチする関数 void qtMessageHundler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); const char *file = context.file ? context.file : ""; const char *function = context.function ? context.function : ""; switch (type) { case QtDebugMsg: qtMessagebuf = QString("%1: Debug: %2, file: %3, line: %4, function: %5").arg("Qt").arg(localMsg.constData()).arg(file).arg(context.line).arg(function); break; case QtInfoMsg: qtMessagebuf = QString("%1: Info: %2, file: %3, line: %4, function: %5").arg("Qt").arg(localMsg.constData()).arg(file).arg(context.line).arg(function); break; case QtWarningMsg: qtMessagebuf = QString("%1: Warning: %2, file: %3, line: %4, function: %5").arg("Qt").arg(localMsg.constData()).arg(file).arg(context.line).arg(function); break; case QtCriticalMsg: qtMessagebuf = QString("%1: Critical: %2, file: %3, line: %4, function: %5").arg("Qt").arg(localMsg.constData()).arg(file).arg(context.line).arg(function); break; case QtFatalMsg: qtMessagebuf = QString("%1: Fatal: %2, file: %3, line: %4, function: %5").arg("Qt").arg(localMsg.constData()).arg(file).arg(context.line).arg(function); break; } }

メッセージハンドラを登録して メッセージをキャッチする。

qInstallMessageHandler を利用して bug 対策
// qDebug() 出力先を変更する qInstallMessageHandler(qtMessageHundler); // 選択範囲 QString cbtext = cr.selectedText(); QClipboard* cb = QApplication::clipboard(); cb->setText(cbtext); // クリップボードに格納 QString errmsg = qtMessagebuf; if(!errmsg.isEmpty()){ if(errmsg.indexOf("Debug") < 0){ // メッセージの内容をチェック QApplication::beep(); m_mainwin->statusBar()->showMessage("OleSetClipboard error Call OleInitialize", 5000); // QMessageBox::critical(this, QString::fromUtf8("エラー"), // QString::fromUtf8("%1").arg(errmsg)); // OLEのエラー if(errmsg.indexOf("OleSetClipboard")>=0){ // Call OleInitialize to enable clipboard together with FLTK libraries // OLE初期化 HRESULT result = OleInitialize(NULL); if (result) { QMessageBox::critical(this, QString::fromUtf8("エラー"), QString::fromUtf8("Problem with OleInitialization %1").arg(result)); } else { // 再度取得 QClipboard* cb = QApplication::clipboard(); cb->setText(cbtext); // クリップボードに格納 } } } qtMessagebuf.clear(); } // qDebug() 出力先を元に戻す qInstallMessageHandler(0);

これで たまに出るエラーを回避できます。
ハンドラー内でログファイルに出力すると 頻度も分かります。

対処療法ですが 私が行った方法です。
この対策を埋め込むと 全く出なくなってしまいました。
何なのでしょうか。不思議な現象です。

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