2013-06-12 10 views
7

Ho scritto un programma rapido e sgradevole per aiutarmi a visualizzare un aspetto di un progetto su cui sto lavorando. Sebbene abbia lavorato con Qt dalla 4.1.1, non ho mai avuto la necessità di utilizzare il modulo QGraphics *.Come mantenere la larghezza del pixel QPen lo stesso quando si esegue lo zoom in una QGraphicsView

Quando ho iniziato a giocare con il programma, stavo lavorando su un vecchio computer con Windows XP e Qt4.7.0 e Visual Studio 2008. Ora ho appena copiato il file sul mio computer principale con Windows 8. I Ho deciso di fare un tentativo a Qt5, quindi ho installato QtCreator con Qt5.0.2.

Quando compilo lo stesso codice identico a quello creato sulla macchina Qt4.7.0/XP, ottengo un risultato molto diverso.

Questo è quello che vedo sul mio Qt4.7.0 compilazione:

Zoomed-out view from Qt4.7.0/XP compilation

e questo è quello che vedo sul mio Qt5.0.2 compilazione: Zoomed-out view from Qt5.0.2/Win8x64 compilation

Chiaramente c'è un comportamento diverso nel disegno del bordo di ciascun rettangolo. Inoltre, se eseguo lo zoom utilizzando la rotella del mouse, la larghezza del bordo del rettangolo diventa più grande nella compilation Qt5 ma rimane uguale (circa 1 pixel di larghezza) nella compilation Qt4.7.

Come cambio il codice in modo che il comportamento in Qt5 sia lo stesso di Qt4.7?

Ecco il codice completo:

#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(); 
} 

risposta

5

La migliore risposta è data da rpsml sottostante questa. Ma per ragioni storiche lascerò questo qui.

Impostare la larghezza della penna a zero renderà una penna "cosmetico" con una larghezza di 1.

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

Quella è stata una delle prime cose che ho provato, ma no, la bilancia larghezza della penna insieme con gli elementi in QT5 ma non in Qt4.7 – RobbieE

+1

la documentazione per QPen :: setWidth() dicono "Una larghezza della linea dello zero indica una penna cosmetica. Ciò significa che la larghezza della penna viene sempre disegnata di un pixel, indipendentemente dalla trasformazione impostata sul pittore. " hai provato a impostare la larghezza su 0? –

+0

Questo è tutto !!! Grazie Cory. Il valore predefinito deve essere cambiato tra le versioni. Crea una risposta e ti darò il merito. – RobbieE

23

Questo è un po 'tardi, ma potrebbe essere utile.

La soluzione proposta funziona bene, ma limita la larghezza della penna. Un'alternativa consiste nell'utilizzare l'istruzione

p.setCosmetic(true); 

Secondo il riferimento Qt (http://qt-project.org/doc/qt-5/qpen.html#isCosmetic)

penne cosmetici sono usati per disegnare tratti che hanno una larghezza costante indipendentemente dalle trasformazioni applicate QPainter sono usato con.

E spiega anche perché impostando la larghezza a zero opere:

Una penna larghezza zero è cosmetici per default; le penne con una larghezza diversa da zero sono non cosmetiche.

+0

Mi piace questa informazione: è pulita (più pulita della soluzione accettata) e offre una maggiore flessibilità – DomTomCat

+0

IMHO, questa è la risposta corretta effettiva. – quimnuss

+0

L'ultima metà della frase è piuttosto ambigua: "Una penna a larghezza zero è estetica per impostazione predefinita, le penne con una larghezza diversa da zero non sono estetiche.". Se leggi solo l'ultima metà "le penne con una larghezza diversa da zero non sono cosmetici". quindi una larghezza della penna diversa da zero NON dovrebbe essere cosmetica, indipendentemente da ciò che si imposta in 'setCosmetic'. Questo è davvero il comportamento che vedo durante i test (PyQt4.7) – Peter

Problemi correlati