2013-06-12 11 views
7

私が取り組んでいるプロジェクトの側面を視覚化するための素早く厄介なプログラムを書きました。私は4.1.1以降Qtで作業してきましたが、QGraphics *モジュールを使用する必要はありませんでした。QGraphicsViewのズームイン時にQPenピクセル幅を同じに保つ方法

私はプログラムでラウンドを開始したとき、Windows XPとQt4.7.0とVisual Studio 2008を実行している古いコンピュータで作業していました。今はWindows 8を実行しているメインコンピュータにファイルをコピーしました。私はQt5.0.2でQtCreatorをインストールしたので、Qt5にショットを与えることに決めました。

私がQt4.7.0/XPマシンで作成したのとまったく同じコードをコンパイルすると、私は大きく異なる結果になります。

これは私が私のQt4.7.0のコンパイルに表示されるものです。

Zoomed-out view from Qt4.7.0/XP compilation

、これは私が私Qt5.0.2のコンパイルに表示されるものです。 Zoomed-out view from Qt5.0.2/Win8x64 compilation

明らかで異なる動作があります各矩形の境界の描画。また、マウスホイールを使用してズームインすると、Qt5コンパイルでは矩形の境界線の幅が大きくなりますが、Qt4.7コンパイルでは同じ(約1ピクセル幅)のままです。

Qt5の動作がQt4.7と同じになるようにコードを変更するにはどうすればよいですか?

はここで完全なコードです:

#include <QApplication> 
#include <QGraphicsScene> 
#include <QGraphicsView> 
#include <QGraphicsRectItem> 
#include <QWheelEvent> 

#include <QSqlDatabase> 
#include <QSqlQuery> 
#include <QSqlRecord> 
#include <QVariant> 
#include <QSqlError> 
#include <QMessageBox> 

class ItemData : public QSqlRecord{ 
public: 
    ItemData(QSqlRecord const &rec) : QSqlRecord(rec) {} 

    qreal left() const { return value(0).toDouble(); } 
    qreal top() const { return value(1).toDouble(); } 
    qreal width() const { return value(2).toDouble() - left(); } 
    qreal height() const { return value(3).toDouble() - top(); } 
    QRectF rect() const { return QRectF(left(), top(), width(), height()); } 
    QString barcode() const { return value(4).toString(); } 
    QString msaName() const { return value(5).toString(); } 
    QString msaDescription() const { return value(6).toString(); } 
    QString hsaName() const { return value(7).toString(); } 
    QString hsaDescription() const { return value(8).toString(); } 
}; 

class DSAItem : public QGraphicsRectItem{ 
public: 
    DSAItem(ItemData const &data, QGraphicsItem *parent = 0) 
     :QGraphicsRectItem(parent) { 
      setFlags(QGraphicsItem::ItemIsSelectable); 
      setRect(data.rect()); 
      QString tip = "<p><b>%1</b></p><p><b>MLSA</b><br/>%2<br/>%3</p><p><b>HLSA</b><br/>%4<br/>%5</p>"; 
      setToolTip(tip.arg(data.barcode(), data.msaName(), data.msaDescription(), data.hsaName(), data.hsaDescription())); 
      if(data.barcode() == "1010100101" || data.barcode() == "1010100114"){ 
       colour = QColor(Qt::red); 
      } else { 
       colour = QColor(Qt::yellow); 
      } 
      colour.setAlphaF(.5); 
      setBrush(QBrush(colour)); 
    } 

    QVariant itemChange(GraphicsItemChange change, QVariant const &value){ 
     if (change == QGraphicsItem::ItemSelectedHasChanged){ 
      QColor c = value.toBool() ? QColor(Qt::green) : colour; 
      c.setAlphaF(.5); 
      setBrush(QBrush(c)); 
      update(rect()); 

     } 
     return QGraphicsRectItem::itemChange(change, value); 
    } 

private: 
    QColor colour; 
}; 

class View : public QGraphicsView { 
public: 
    View(QWidget *parent = 0): QGraphicsView(parent){ 
     populateScene(); 
     setScene(&scene); 
     rotate(-90); 
     scale(1.0, -1.0); 
     setDragMode(ScrollHandDrag); 
    } 

protected: 
    void wheelEvent(QWheelEvent *e){ 
     setTransformationAnchor(QGraphicsView::AnchorUnderMouse); 

     double scaleFactor = 1.15; 
     if (e->delta() > 0){ 
      scale(scaleFactor, scaleFactor); 
     } else { 
      scale(1/scaleFactor, 1/scaleFactor); 
     } 
    } 

private: 
    void populateScene(){ 
     QSqlDatabase db = QSqlDatabase::addDatabase("QODBC"); 
     //db credentials here 

     QString errorMessage; 
     bool ok = db.open(); 
     if (ok){ 
      QSqlQuery query(db); 
      QString sql = //query string here 

      if (query.exec(sql)){ 
       while(query.next()){ 
        scene.addItem(new DSAItem(query.record())); 
       } 
      } else { 
       errorMessage = query.lastError().text(); 
      } 
     } else { 
      errorMessage = db.lastError().text(); 
     } 

     if (!errorMessage.isEmpty()){ 
      QMessageBox::critical(0, "Database Error", errorMessage); 
     } 
    } 

private: 
    QGraphicsScene scene; 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    View view; 
    view.show(); 

    return a.exec(); 
} 

答えて

5

最良の答えは、この1以下rpsmlで与えられます。しかし歴史的な理由から私はここに残します。ゼロにペンの幅を設定

これは少し遅れているが、役に立つかもしれませんそれ1.

QPen p = pen(); 
p.setWidth(0) 
setPen(p); 
+0

しかし、いや、Qt5ではなくQt4.7 – RobbieE

+1

QPen ::にsetWidth用ドキュメント内のアイテムと一緒にペン幅のスケールは()「ゼロの線幅を言いますこれは、ペンの幅は、ペインタの変換セットとは関係なく、常に1ピクセル幅で描画されることを意味します。あなたは0に幅を設定しようとしましたか? –

+0

それはそれです!コリーに感謝します。バージョン間でデフォルト値が変更されている必要があります。答えをつくると私はあなたに信用を与えるでしょう。 – RobbieE

23

の幅と「化粧品」のペンになります。

提案された解決策は問題なく動作しますが、ペンのサイズが制限されます。代替的には関係なく、任意の変換の彼らはQPainterのに適用される命令のQtリファレンス(http://qt-project.org/doc/qt-5/qpen.html#isCosmetic)によれば

化粧ペンが一定の幅を有するストロークを描画するために使用される

p.setCosmetic(true); 

を使用することですと一緒に使用。

ゼロ作品に幅を設定する理由、それはまた、説明:

ゼロ幅のペンは、デフォルトでは化粧品です。幅がゼロでないペンは非化粧品です。

私が試した最初のものの一つであった
+0

私はこの情報が気に入っています - それは清潔で(受け入れられた解決策よりもきれいです)、より柔軟なものを提供します – DomTomCat

+0

IMHO、これは実際の正解です。 – quimnuss

+0

最後の半分の文はかなり曖昧です: "ゼロ幅のペンはデフォルトでは化粧です;幅がゼロでないペンは非美容です。"あなたが最後の半分だけを読むならば、非ゼロの幅を持つペンは化粧品ではありません。 'setCosmetic'で何を設定していても、ペンの幅をゼロにしないでください。それは確かに私がテスト(PyQt4.7)時に見る動作です – Peter