Anzeige:
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 28

Thema: [Qt] Linien dynamisch auf Label zeichnen

  1. #1
    Registrierter Benutzer
    Registriert seit
    12.03.2009
    Beiträge
    36

    [Qt] Linien dynamisch auf Label zeichnen

    Hallo,
    ich schreibe an einem Programm (abgewandelter ImageViewer aus den Beispielprogrammen) und möchte ein Bild verkleinern, dass gerade auf dem QLabel angezeigt wird. Dazu öffne ich einen Dialog und wähle aus, wie viele Pixel rechts, links, oben und unten abgeschnitten werden sollen. Als Hilfe möchte ich gerne, dass 4 (grüne) Linien auf dem Bild (QLabel) gezeigt werden, die symbolisieren, wo abgeschnitten wird.
    So etwa:
    ......|....................|.......
    ......|....................|.......
    -------------------------
    ......|....................|.......
    ......|....................|.......
    ......|....................|.......
    ......|....................|.......
    -------------------------
    ......|....................|.......
    ......|....................|.......
    Da ich über den Dialog die Position der Linien verändern würde, müssen sie also "beweglich" sein (oder ich muss das Originalbild halt immer neu laden und dann die Linien neu draufsetzen).
    Es wäre toll, wenn jemand eine Idee hätte.
    Vielen Dank!
    melanie

  2. #2
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Also ich würde so etwas mit QRubberBand machen.
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  3. #3
    Registrierter Benutzer
    Registriert seit
    12.03.2009
    Beiträge
    36
    QRubberBand klingt nach der Class Reference nach dem was ich suche!
    Bei der Umsetzung bräuchte ich noch etwas Unterstützung

    Hier mal ein paar Auszüge aus einem Minimalprogramm:
    Die Oberfläche habe ich mit dem QtDesigner gemacht. Es ist eigentlich nichts besonderes. 2 Menüpunkte, 1: Rechteck zeichnen (action_Draw_Rect) und 2: Beenden (action_Beenden)

    main.cpp:
    Code:
    #include <Qt/qapplication.h>
    #include "MainWindow.h"
    
    int main(int argc, char* argv[])
    {
    	QApplication app(argc, argv);
    	MainWindow mainWindow;
    	mainWindow.show();
    	return app.exec();
    }
    MainWindow.h:
    Code:
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <Qt/QMainWindow.h>
    #include "Forms/Ui_MainWindow.h"
    
    class QAction;
    class QLabel;
    class QMenu;
    
    class MainWindow : public QMainWindow, protected Ui_MainWindow
    {
    	Q_OBJECT
    
    public:
    	MainWindow(QWidget *parent = 0);
    
    private slots:
    	void drawrect();
    
    private:
    	QImage GenerateQImage(int value);
    	QLabel *imageLabel;
    	QRubberBand *rubberBand;
    };
    
    #endif
    MainWindow.cpp:
    Code:
    #include <Qt/QLabel.h>
    #include "MainWindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
    	: QMainWindow(parent)
    {
    	setupUi(this);
    	imageLabel = new QLabel(this->centralWidget());	//platziert das Label auf dem Fenster
    	imageLabel->setBackgroundRole(QPalette::Base);
        imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
        imageLabel->setScaledContents(true);
    
    	//Startbild generieren
    	QImage image = GenerateQImage(255);
    	imageLabel->setPixmap(QPixmap::fromImage(image));
    	imageLabel->setVisible(true);
    
    	connect(action_Beenden, SIGNAL(triggered()), this, SLOT(close()));
    	connect(action_Draw_Rect, SIGNAL(triggered()), this, SLOT(drawrect()));
    }
    
    QImage MainWindow::GenerateQImage(int value)
    {
    	QImage img_gray(200, 200, QImage::Format_Indexed8);
        // Colortable erstellen für Graustufen
    	QVector<QRgb> grayscales;
    	for (int i=0; i<256; ++i)
    		grayscales.push_back(qRgb(i,i,i));
    	// colortable dem graustufen bild zuweisen
    	img_gray.setColorTable(grayscales); 
    
    	for (int z=0; z<200; ++z)
    		for (int x=0; x<200; ++x)
    		{
    			img_gray.setPixel(x,z, value);
    		}
    	return img_gray;
    }
    
    void MainWindow::drawrect()
    {	
    	if (!rubberBand)
    		rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
    	rubberBand->setGeometry(10,10,50,50);
        rubberBand->show();
    }
    Was mache ich falsch und wie bekomme ich jetzt ein Rechteck der Größe 50x50 an die Position (10,10) auf dem imageLabel?
    Danke!!!

  4. #4
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Vermute mal falsche Vererbung.
    PHP-Code:
    #ifndef RUBBERBAND_H
    #define RUBBERBAND_H

    #include <QtCore>
    #include <QtGui>

    class Rubberband : public QMainWindow
    {
      
    Q_OBJECT

      
    private:
        
    QPoint startPoint;
        
    QWidgetcentral;
        
    QRubberBandband;

      protected:
        
    void mousePressEvent(QMouseEvent *);
        
    void mouseMoveEvent(QMouseEvent *);

      public:
        
    Rubberband();
        ~
    Rubberband();
    };

    #endif 
    Code
    PHP-Code:
    #include "rubberband.h"

    /* QtCore */
    #include <QtCore>
    #include <QtGui>

    Rubberband::Rubberband()
      : 
    QMainWindow ()
      , 
    startPoint QPoint0) )
    {
      
    setObjectName "rubberband" );
      
    setMinimumWidth 400 );
      
    setMinimumHeight 400 );

      
    central = new QWidgetthis );
      
    central->setObjectName "rubberband.central" );
      
    central->setAutoFillBackground false );
      
    central->setMouseTracking false );
      
    central->setStyleSheet "*{background-color:gray;}" );

      
    band = new QRubberBand(QRubberBand::Rectangle,central);
      
    band->setGeometry00100100 );
      
    band->show();

      
    setCentralWidget central );
    }

    void Rubberband::mousePressEvent(QMouseEvent *event)
    {
      
    startPoint event->pos();
      
    band->setGeometry(QRect(event->pos(), QSize()));
    }

    void Rubberband::mouseMoveEvent(QMouseEvent *event)
    {
      
    band->setGeometry(QRect(startPointevent->pos()).normalized());
    }

    Rubberband::~Rubberband()
    {} 
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  5. #5
    Registrierter Benutzer
    Registriert seit
    12.03.2009
    Beiträge
    36
    Jetzt bin ich schon einen Schritt weiter, aber leider taucht jetzt ein neuer Fehler auf.
    Beim Programmende erscheint der Fehler:
    "Run-Time Check Failure #2 - Stack around the variable 'mainWindow' was corrupted."

    Hier der Programmcode:
    main.cpp:
    Code:
    #include <Qt/qapplication.h>
    #include "MainWindow.h"
    
    int main(int argc, char* argv[])
    {
    	QApplication app(argc, argv);
    	MainWindow mainWindow;
    	mainWindow.show();
    	return app.exec();
    }
    MainWindow.h:
    Code:
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <Qt/QMainWindow.h>
    #include "Forms/Ui_MainWindow.h"
    
    class QAction;
    class QLabel;
    class QMenu;
    
    class MainWindow : public QMainWindow, protected Ui_MainWindow
    {
    	Q_OBJECT
    
    public:
    	MainWindow(QWidget *parent = 0);
    
    private:
    	QImage GenerateQImage(int value);
    	QLabel *imageLabel;
    	QRubberBand *rubberBand;
    };
    
    #endif
    MainWindow.cpp:
    Code:
    #include <Qt/QLabel.h>
    #include "MainWindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
    	: QMainWindow(parent)
    {
    	setupUi(this);
    	imageLabel = new QLabel(this->centralWidget());
    	imageLabel->setBackgroundRole(QPalette::Base);
        imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
        imageLabel->setScaledContents(true);
    
    	//Startbild generieren
    	QImage image = GenerateQImage(255);
    	imageLabel->setPixmap(QPixmap::fromImage(image));
    	imageLabel->setVisible(true);
    
    	rubberBand = new QRubberBand(QRubberBand::Rectangle,imageLabel);
    	rubberBand->setGeometry( 0, 0, 100, 100 );
    	rubberBand->show(); 
    
    	connect(action_Beenden, SIGNAL(triggered()), this, SLOT(close()));
    }
    
    QImage MainWindow::GenerateQImage(int value)
    {
    	QImage img_gray(200, 200, QImage::Format_Indexed8);
        // Colortable erstellen für Graustufen
    	QVector<QRgb> grayscales;
    	for (int i=0; i<256; ++i)
    		grayscales.push_back(qRgb(i,i,i));
    	// colortable dem graustufen bild zuweisen
    	img_gray.setColorTable(grayscales); 
    
    	for (int z=0; z<200; ++z)
    		for (int x=0; x<200; ++x)
    		{
    			img_gray.setPixel(x,z, value);
    		}
    	return img_gray;
    }

  6. #6
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Also nur mit einigen kleinen Veränderungen, damit das hier kompiliert, läuft dein Programm bei mir ohne Fehlermeldung. Valgrind meldet auch nichts verdächtiges. Ich kann auch im Code soweit keinen Fehler entdecken.

    Hast du alle generierten Dateien auf dem neusten Stand? Generier noch mal alles neu und kompiliere frisch durch.

  7. #7
    Registrierter Benutzer
    Registriert seit
    12.03.2009
    Beiträge
    36
    Jetzt läuft es auch bei mir. Ich habe mal das Projekt bereinigt usw. Doofe Sache. Ich habe nämlich auch nicht verstanden, was da falsch sein soll. Vielen Dank für den Tipp!!!

    Aber ich wäre ja nicht ich, wenn ich nicht schon wieder eine neue Frage hätte:
    Wie kann ich die Farbe QRubberBand ändern. Ich hätte gerne ein ungefülltes (transparentes) Rechteck mit z.B. grünem Rahmen. (Meine Bilder sind immer Graustufenbilder, weshalb ein grauer Rahmen eher ungünstig ist.)

    Vielen Dank

  8. #8
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Das geht nur wenn du die Klasse QRubberBand ableitest und mit "initStyleOption" diese Veränderst.
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  9. #9
    Registrierter Benutzer
    Registriert seit
    12.03.2009
    Beiträge
    36
    Oh je, das kann ich fürchte ich nicht. Ich definiere also eine neue Klasse, die von QRubberBand erbt. Hier mal ein bisschen Code dazu, wie ich mir das vorstelle. Allerdings fehlen viele Sachen und ich weiß überhaupt nicht, wie ich mit initStyleOption umgehen soll:

    myRubberBand.h:
    Code:
    #ifndef MYRUBBERBAND_H
    #define MYRUBBERBAND_H
    
    class MyRubberBand: public QRubberBand
    {
       Q_OBJECT
    
    public:
       MyRubberBand(Shape s = Rectangle, QWidget *parent = 0);
    
    protected:
       virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index ) const
    };
    
    #endif //MYRUBBERBAND
    myRubberBand.cpp:
    Code:
    #include "MyRubberBand.h"
    
    MyRubberBand::MyRubberBand(Shape s, QWidget * parent):
       QRubberBand(s, parent)
    {}

  10. #10
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Hier auf die schnelle ein Beispiel (nicht getestet)
    PHP-Code:
    class RubberBand : public QRubberBand
    {
      
    Q_OBJECT

      
    protected:
        
    void initStyleOption QStyleOptionRubberBand * ) const;
        
    void paintEvent(QPaintEvent * );

      public:
        
    RubberBand QWidget parent );
    }; 
    PHP-Code:
    RubberBand::RubberBandQWidget parent )
      : 
    QRubberBand (QRubberBand::Rectangle,parent)
    {}

    void RubberBand::initStyleOption QStyleOptionRubberBand option ) const
    {
      if (!
    option)
        return;

      
    option->initFrom(this);
    }

    void RubberBand::paintEventQPaintEvent event )
    {
      
    QPainter painter(this);

      
    QBrush b;
      
    b.setStyle Qt::SolidPattern );
      
    b.setColor Qt::red );

      
    painter.fillRectevent->rect(), );
      
    painter.beginNativePainting();
      
    painter.endNativePainting();

    Geändert von undefined (25-08-2010 um 17:47 Uhr)
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  11. #11
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Ehrlich gesagt glaube ich nicht, dass es zum Ändern der Farbe nötig oder hilfreich ist, eine neu initStyleOption Funktion zu schreiben. (Überschrieben werden kann diese Funktion übrigens gar nicht, weil sie nicht virtuell ist)

    Wie das zu machen wäre scheint mir einfach nicht dokumentiert zu sein, aber mit Qt 4.6.3 geht es jedenfalls indem die Farbe für "WindowText" des QRubberBand-Objektes gesetzt wird. Zumindest der Rahmen wird nämlich mit dieser Farbe gezeichnet.

    Das sähre dann ungefähr so aus, beispielsweise:
    Code:
    [Im MainWindow-Konstruktor]
    [...]
    rubberBand = new QRubberBand(QRubberBand::Rectangle,imageLabel);
            QPalette pal = rubberBand->palette();
            pal.setColor(QPalette::WindowText, QColor("red") );
            rubberBand->setPalette(pal);
    [...]
    Wie man auch noch eine Hintergrundfarbe setzt, das weiß ich nicht. Ich weiß bloß, das es Code in der Datei src/gui/styles/qcommonstyle.cpp der Qt-Sourcen gibt, die zum Zeichnen der Rubberbands benutzt wird. Da könnte man dann evtl. mal reingucken wie das ginge. Aber wie gesagt, man verlässt damit das was von der Doku garantiert wird.

  12. #12
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Geht schon und ist in einer meiner Projekte im einsatz um den OpenSuSE KDE4 Style (Patch) zu kicken der bei diesem Program hinderlich ist.
    http://gitweb.hjcms.de/cgi-bin/index...rubberband.cpp
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  13. #13
    Registrierter Benutzer
    Registriert seit
    23.05.2004
    Beiträge
    592
    Bezüglich initStyleOption neu schreiben/überschreiben:
    Geht schon und ist in einer meiner Projekte im einsatz um den OpenSuSE KDE4 Style (Patch) zu kicken der bei diesem Program hinderlich ist.
    Aber wie wird die Funktion denn aufgerufen? Sie ist nicht virtuell markiert, auch nicht in einer Basisklasse. Kann es sein, dass der wichtige Part bei dir vielmehr ist, dass du
    paintEvent überschreibst? Damit kann man natürlich ganz schön was anstellen...

  14. #14
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Ja der wichtige Part ist in der tat der paintEvent. Soweit ich mich erinnere bekommt die Methode initStyleOption nur dann eine Bedeutung wenn ein Style Plugin geladen wird das versucht mit CE_RubberBand diesen zu bearbeiten. OpenSuSE hatte bei KDE4.1 hier mal einen Bug produziert weshalb ich das immer noch drinne habe.
    Wenn man den Style an dieser Stelle ändern möchte geht das nur in dem man ein Style Plugin hinzu lädt - dies wird unter QStyleOption beschrieben.
    Geändert von undefined (26-08-2010 um 14:34 Uhr)
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  15. #15
    Registrierter Benutzer
    Registriert seit
    12.03.2009
    Beiträge
    36
    Hallo,
    ich muss diesen Thread leider nochmal aufrollen... Mit dem QRubberBand komme ich gut klar (ich habe das mit der Farbe nicht hinbekommen, aber es geht auch so).
    Jetzt habe ich allerdings eine andere Aufgabenstellung. Ich müsste nun Dreiecke zeichnen. Ich würde das denke ich gerne mit QPainter machen und dann drawPolygon().
    Aus der Dokumentation habe ich folgendes Beispiel:
    Code:
        static const QPointF points[3] = {
         QPointF(10.0, 80.0),
         QPointF(20.0, 10.0),
         QPointF(80.0, 30.0),
        };
    
        QPainter painter(this);
        painter.drawPolyline(points, 3);
    Eingebaut in mein "altes Minimalprogramm" habe ich dann diesen Quellcode:

    MainWindow.h:
    Code:
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <Qt/QMainWindow.h>
    #include "Forms/Ui_MainWindow.h"
    
    class QAction;
    class QLabel;
    class QMenu;
    
    class MainWindow : public QMainWindow, protected Ui_MainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = 0);
    
    private:
        QImage GenerateQImage(int value);
        QLabel *imageLabel;
    };
    
    #endif
    MainWindow.cpp:
    Code:
    #include <Qt/QLabel.h>
    #include <QtGui/QtGui>
    #include "MainWindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
        setupUi(this);
        imageLabel = new QLabel(this->centralWidget());    //platziert das Label auf dem Fenster
        imageLabel->setBackgroundRole(QPalette::Base);
        imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
        imageLabel->setScaledContents(true);
    
        //Startbild generieren
        QImage image = GenerateQImage(255);
        imageLabel->setPixmap(QPixmap::fromImage(image));
        imageLabel->setVisible(true);
    
         static const QPointF points[3] = {
         QPointF(10.0, 80.0),
         QPointF(20.0, 10.0),
         QPointF(80.0, 30.0),
        };
    
        QPainter painter(imageLabel);
        painter.drawPolyline(points, 3);
    
        connect(action_Beenden, SIGNAL(triggered()), this, SLOT(close()));
    }
    
    QImage MainWindow::GenerateQImage(int value)
    {
        QImage img_gray(200, 200, QImage::Format_Indexed8);
        // Colortable erstellen für Graustufen
        QVector<QRgb> grayscales;
        for (int i=0; i<256; ++i)
            grayscales.push_back(qRgb(i,i,i));
        // colortable dem graustufen bild zuweisen
        img_gray.setColorTable(grayscales); 
    
        for (int z=0; z<200; ++z)
            for (int x=0; x<200; ++x)
            {
                img_gray.setPixel(x,z, value);
            }
        return img_gray;
    }
    Irgendwas stimmt natürlich nicht allerdings habe ich nur Anleitungen mit paintEvent gefunden (die ich auch nicht wirklich verstanden habe). Kann mir jemand helfen

    Die Fehlermeldung, die angezeigt wird lautet übrigens: QPainter::begin: Paint device returned engine == 0, type: 1
    Geändert von melanie (15-09-2010 um 15:33 Uhr) Grund: Fehlermeldung vergessen....

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •