6

私はこのコードをライブラリでかなり長い間実行してきました:

MyClass::MyClass() 
  : QDialog()
{
    // (...)
    setWindowFlags( Qt::CustomizeWindowHint | Qt::WindowTitleHint );
    // (...)
}

次に、ライブラリのさまざまな部分を変更した後、突然次のメッセージが表示されます。

error C2664: 'QWidget::setWindowFlags': cannot convert parameter 1 from 'int' to 'Qt::WindowFlags'

どうやらそれは|を見つけられません QFlagsクラスによって提供される演算子のオーバーロードにより、|の結果が QFlags構文ではなくintを返します。

結果を手動でキャストして機能さ(Qt::WindowFlags)せることはできますが、QFlagsを使用すると、通常、この種のキャストは不要になります。

どのような変化がこの行動につながる可能性があるのか​​、何か考えはありますか?

<QtGui/QDialog>通常はどちらで十分かを含めます。含めても<QtCore/QFlags>動作は変わりません。

4

3 に答える 3

6

5.12.0以降、これは次のcommitによって修正される必要があります: "Declare the operator| in the Qt namespace for QFlags in that namespaces". 5.12.0 より前は、Qt はその列挙演算子を名前空間ではなくグローバル名前空間 ( qnamespace.hを参照) に配置していましたQt

問題は、現在の名前空間に一致する別の演算子がある場合、コンパイラは親スコープを検索しないことです。したがって、名前空間内の任意の型の演算子にオーバーロードを追加するとすぐに、Qt のオーバーロードは一致のセットに含まれなくなります。ADLは通常、型と同じ名前空間で宣言された演算子を解決するために使用されますが、演算子が別の名前空間にある場合、これは機能しません。

本当の解決策は、Qt が演算子を操作対象の型と同じ名前空間に配置することでした。これは 5.12.0 で行われました。以前のバージョンに行き詰まっている場合は、オペレーターを自分でインポートできます。

using ::operator|;
setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);

これは、意図しない結果をもたらす可能性があることに注意してください。使用できないコンテキストで多くの名前を使用できるようにする可能性があるためです。

于 2016-02-06T01:28:26.117 に答える
2

ソース コードを調べてQ_DECLARE_OPERATORS_FOR_FLAGS、コンパイル エラーが発生する前の名前空間のどこかで独自のフラグを宣言していないかどうかを確認してください。

@isanaeが言ったように、If there is another operator that matches in the current namespace, .... したがって、一致する可能性のある他の演算子を配置しないでください。

Q_DECLARE_OPERATORS_FOR_FLAGS解決策は、Qt と同じように、独自の宣言をすべてグローバル名前空間に配置することです。

これが役立つことを願っています。すべてを unity ビルド環境に置いたときに同じ問題が発生し、ソース コードの順序を入れ替えて、最終的にこの問題の原因となっているコード スニペットを見つけましたQ_DECLARE_OPERATORS_FOR_FLAGS

于 2016-05-11T04:02:12.687 に答える
0

|を分離しようとしましたか 関数呼び出しからの式?何かのようなもの:

// ..
Qt::WindowFlags flags = Qt::CustomizeWindowHint | Qt::WindowTitleHint;
setWindowFlags( flags );
// ...

問題が正確にどこにあるかを確認するためだけに...

インクルードの問題である場合は、#include <QtGui>

于 2012-05-25T13:58:16.713 に答える