Slot in Slot auslösen

Alles rund um die Programmierung mit Qt
kannaum
Beiträge: 73
Registriert: 31. Januar 2010 09:57

Beitrag von kannaum »

Ok vielen Dank es geht jetzt alles.

Erkannte zuerst nicht wirklich den Sinn das QLabel zu resizen.

Wenn ich das ganze ohne dieser Scroll Area mache geht alles perfekt.
Wenn ich dann aber folgendes hinzufüge wird das Bild beim zoomen sofort grau:

Code: Alles auswählen

            scrollArea = new QScrollArea;
            scrollArea->setWidget(label);
Also wieder meine Fragen:
1: Was soll das mit der SCrollarea bringen?
2: Was ist an meiner Scrollarea falsch?

Beim Dialog habe cih jetzt auch den Fehler gefunden.
Hatte den Code von einem Tread hier im Forum und da hat anscheinend auch das show() gefehlt.

mfg
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

für modale Dialoge brauchst du exec() ...

Lade doch mal ein Bild einer 10 MP Kamera ohne ScrollArea .. dann siehst du erstmal von den 2580x3159 Pixeln ungefähr die obere Ecke ... das Scrollarea sorgt dafür das die Scrollbalken bei Bedarf angezeigt werden.
Wenn du das Label einmal ins Scrollarea gepackt hast bleibt das da, also beim Zoomen NICHT wieder tun. Du setzt bloss ein neues Pixmap und sagst dem Label es soll jetzt dessen Größe haben (das passiert bei dem sizeHint() Zeug). Wenn unter einem klein gescalten Bild ein (dunkel)grauer Bereich auftaucht, dann ist das Bild und damit das Label so klein, dass es nicht mehr das ganze QScrollArea ausfüllt und damit dessen Hintergrundfarbe durchkommt. Es hat deshalb eine andere Farbe weil du das mit area->setBackgroundRole(QPalette::Dark); so bestimmt hast ... versuch da mal QPalette::NoRole dann sollte es nicht so hervorstechen.
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
kannaum
Beiträge: 73
Registriert: 31. Januar 2010 09:57

Beitrag von kannaum »

So nach einiger Zeit melde ich mich wieder mit einem Problem und anderen Fragen:

1. Mein größtes Problem.
Mitlerweile kann man auch schon einen Screenshot mit dem Programm machen.
Habe dafür auch noch einen Einstellungsdialog, wie bereits erwähnt, bei dem man Format und Ordner wählen kann.
Soweit kein Problem.

Für meine eigene Übung (und weil ich zugegeben mit den Qt-Xml Sachen einfach nicht zurecht komme) habe ich selber eine kleine Xml-Api geschrieben.
Für die Einstellungen beispielsweise habe ich folgende Datei einstellungen.txt:
<screenshot>
<format>
.jpg
</format>
<pfad>
D:/
</pfad>
</screenshot>
Für das hantieren damit habe ich ein paar Methoden, unter anderem:

Code: Alles auswählen

bool update(string name, string type, string content, string file2) {
        //Inhalt der übergebenen Datei öffnen und in Variable schreiben
        string file = open_file(file2);
        //Position für den Anfang des Einfügens finden
        int pos = file.find(name+">", 0);
        int pos2 = file.find("<"+type+">", pos);
        int laenge = type.length();
        pos2 += laenge;
        pos2 += 2;
        //Position für das Ende des Einfügens finden
        int pos3 = file.find("</"+type+">", pos2);
        int pos4 = pos3 - pos2;
        file.erase(pos2, pos4);
        file.insert(pos2, content);
        bool ok = save_file(file);
        if (!ok) {
            return false;
        } {
        return true;
    }
    }
MIt der Methode soll man dann beispielsweise das Format in der Datei einstellungen geändert werden.

Für diese Methode habe ich noch folgende, um es ein bisschen übersichtlicher zu machen:

Code: Alles auswählen

    string open_file() {
        ifstream file_input;
        file_input.open("einstellungen.txt", ios_base::in);
        if (!file_input) {
            return "Datei konnte nicht geöffnet werden";
        }
        string file_content;
        while (file_input.good()) {
            file_content += (char) file_input.get();
        }
        file_input.close();
        return file_content;
    }
Diese Methode gibt den Inhalt der Datei eisntellungen.txt zurück und funktioniert perfekt (diese Methode wird auch von einer anderen Methode verwendet, die einwandfrei funktioniert).

Dann noch als letztes eine Methode, die dann wieder den neuen Inhalt der Datei wieder in die Datei speichert:

Code: Alles auswählen

    bool save_file(string file) {
        fstream file_output;
        file_output.open("einstellungen.txt", ios_base::in);
        if (!file_output) {
            return false;
        }
        file_output << file;
        file_output.close();

        return true;
    }
Aufrufen tue ich es folgendermaßen:

Code: Alles auswählen

        api.update("screenshot", "format", CombCur);
Damit geht aber leider gar nichts.
Bekomme auch keine Fehlermeldung etc.

Zum Test habe ich noch an der selben Stelle folgendes aufgerufen:

Code: Alles auswählen

api.save_file("hallo");
In der Datei einstellungen.txt ändert sich aber gar nichts.


Wäre sehr nett wenn jemand den Fehler finden würde!


Und dann noch 2 Fragen zu deinem Code padreigh:
1. Wieso bindest du Headerdateien mit
#include <QtGui/QFrame>
und nicht" normal" mit
#include <QFrame>
ein?

2. Ist es nur gewohnheit, oder hat es einen anderen Grund, dass du die "Methodenkörper" (mir fällt gerade nciht das passende Wort ein) in die Header Datei schreibst?

mfg
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Wenn du eine datei schreiben willst, nimmst du ofstream - der std::ios_base::in macht aus dem fstream einen ifstream, welcher Dateien einliest.

Kurze Frage: Wenn du programmierst, wie gehst du vor? Wild drauf losschreiben? googlen + code zusammenclicken? Überlegen und dann in der Doku nachschlagen, welche Klassen + Funktionen für deinen Zweck zielführend sind?

@padreigh.2:
Google nach "inline".
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Das mit den Includes mache ich aus Gewohnheit, so bekomme ich ein Gefühl/Gedächnis wozu die gehören ... QtGui , QtCore, QtXML, ... ausserdem hab ich halt nur den Hauptordner im Includepath.

Inlinen mache ich im Forum damit ich nicht ne cpp und ne .h und vielleicht noch ne .pro und main.cpp posten muss ... ich inline nur höchst selten so "dicke" Sachen, das ist eher was für getter / setter oder Zeug das wenig Overhead erzeugt.

Wenn du eh Qt nimmst, warum dann std::string? Warum ifstream? Nimm QFile & QTextStream, schau in die API und klick auf "Mehr..." und dir wird in 60% der Fällen geholfen, in 30% musste vielleicht noch ein Example bemühen (vA bei so Sachen wie Plugins, Model/View, Networkzeug) und dann kannste immer noch im Forum fragen.

Wenn du dir das Leben schwer machen willst mach halt dein eigenes XML, ich nutz lieber die Klassen die dafür da sind :) nach ca 1h Einlesen und rumprobieren sind die einfach zu Handhaben gewesen (für mich, das was ich brauche davon). Nutze das was Qt mitbringt, du bindest es warscheinlich eh ein ... genau das selbe gilt für std::string vs QString. Meist bleibt das Zeug sogar STL kompatibel (entweder direkt wie bei iteratoren oder per .toStdString() wenns umbedingt sein muss ...)
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
kannaum
Beiträge: 73
Registriert: 31. Januar 2010 09:57

Beitrag von kannaum »

Erstmal danke an alle:

Habe auch zuerst überlegt das mit qfile zu machen, dachte aber, dass es so nciht viel mehr Arbeit wäre und ich diese Klasse dann auch problemlos in einem Konsolenprogramm verwenden könnte.

@franzf:
Normalerweise mache ich mir zuerst ein paar Gedanken über das Programm, dann schreib ich mit der Hilfe eines Buches und mit einem "stätigen Blick auf die Doku".
Leider habe ich noch nicht so viel Erfahrung mit qt und finde deswegen oft Sachen in der Doku nicht.
Wenn ich irgendwo hängen bleibe, schaue ich dann erstmal 15min auf meinen Code, finde 5 Fehler, das Programm geht aber trotzdem noch nicht und dann google ich das meistens und ab und zu benutz ich dann auch die Forensuche.
Und wenn das alles nichts hilft jammere ich wieder euch an :wink:

mfg
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

kannaum hat geschrieben:Habe auch zuerst überlegt das mit qfile zu machen, dachte aber, dass es so nciht viel mehr Arbeit wäre und ich diese Klasse dann auch problemlos in einem Konsolenprogramm verwenden könnte.
Dafür gibt es auch fertige Sachen. Z.B. rapidxml oder pugixml. Die sind klein und verdammt schnell.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

kannaum hat geschrieben: Habe auch zuerst überlegt das mit qfile zu machen, dachte aber, dass es so nciht viel mehr Arbeit wäre und ich diese Klasse dann auch problemlos in einem Konsolenprogramm verwenden könnte.
Und was hindert Dich daran Qt in einem Konsolenprogramm zu benutzen?
Das was Du da xml nennst ist nichts weiter als eine komplizierte txt-Datei die genau so aufgebaut sein muss wie Du definierst sonst kannst Du sie nicht parsen. Das hat rein garnichts mit xml zu tun ausser dass es so aussieht.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kannaum
Beiträge: 73
Registriert: 31. Januar 2010 09:57

Beitrag von kannaum »

Christian81 hat geschrieben:
kannaum hat geschrieben: Habe auch zuerst überlegt das mit qfile zu machen, dachte aber, dass es so nciht viel mehr Arbeit wäre und ich diese Klasse dann auch problemlos in einem Konsolenprogramm verwenden könnte.
Und was hindert Dich daran Qt in einem Konsolenprogramm zu benutzen?
Das was Du da xml nennst ist nichts weiter als eine komplizierte txt-Datei die genau so aufgebaut sein muss wie Du definierst sonst kannst Du sie nicht parsen. Das hat rein garnichts mit xml zu tun ausser dass es so aussieht.
Und, egal!

Es funktioniert einwandfrei und mehr SChnickschnack brauch ich gar nciht!

@padreigh:
Hast wieder eine Pn.

mfg
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Warum denn eigentlich überhaupt XML? Kennst du QSettings? Für dein flaches XML ist das sicher ein optimales replacement. Wenn du nicht Qt verwenden willst, schau mal in Richtung boost::property_tree, der kann configs als xml, ini, json, info speichern, und wenn du lustig bist kannst du ihn für eigene Config-Kreationen selber erweitern! Und weils gar so schön ist: Das sind nur templates :)

Und mit Schnickschnack hat das wenig zu tun, dass man dir von so einem einfachen "Parser" abrät. Wenn jemand eine Datei ".xml" sieht, die auch wie xml ausschaut, und selber drinnen editiert, und etwas böses macht (z.B. tags+Value in eine Zeile schreibt) ist deine Config dahin... Wenn es fertige Lösungen gibt sollte man möglichst solche verwenden, da man sich sonst am Ende unnötige Fehler einhandeln kann. Wenn du für jede Lib, die du nicht verstehst, gleich eine eigene unvollständige Implementierung schreibst, endet das bald im Chaos. Machst du das dann auch, wenn du Qt ItemView nicht verstehst? Schreibst du dann dein eigenes Qt-Model-View-Dingens?

Frag doch bitte erst nach wenn du etwas nicht verstehst, man kann dir hier sicher helfen!
kannaum
Beiträge: 73
Registriert: 31. Januar 2010 09:57

Beitrag von kannaum »

Ja stimmt ja.

Bin nur manchmal sehr schnell deprimiert und entwickle dann eine "Angst" dagegen :lol:
So wie ich sie auch vor der Konsole habe, da ich da schon sehr oft rumprobiert habe, aber nie irgendetwas schaffte (ich meine jetzt z.B.: ein Programm zu kompilieren, und nicht eines für die Kosole zu schreiben)

NUn wieder zu meinem Programm:
Heute hat mir jemand gesagt, dass bei ihm die jpeg Bilder im Auswahldialog gar nicht angezeigt werden.
Er verwendet Win7.
Ich verwende auch Win7 und bei mir geht es ohne Probleme.

Hat jemand eine Idee von wo das kommen kann?

mfg
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

kannaum
Beiträge: 73
Registriert: 31. Januar 2010 09:57

Beitrag von kannaum »

Ok danke, nur damit ich das jetzt richtig verstehe:

Wenn ich in meinem Programm folgendes ergenze:

Code: Alles auswählen

        qApp->addLibraryPath("plugins/qgif4.dll");
        qApp->addLibraryPath("plugins/qico4.dll");
        qApp->addLibraryPath("plugins/qjpeg4.dll");
und sich die Dateien im richtigen Ordner befinden geht das schon?

D.h: ich muss dann die .dll Dateien auch mit dem Programm ausliefern oder?

mfg
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Sorry aber wo steht auch nur ein Wort von dem was du das vesuchst in er Doku? Zumal sich die Frage erübrigen würde wenn man die Foren-Suche auch mal benutzen würde...
Be sure to distribute any Qt plugins that you need with your application, and note that each type of plugin should be located within a specific subdirectory (such as imageformats or sqldrivers) within your distribution directory, as described below.
Was ist daran nicht zu verstehen? Ordner imageformats unterhalb des Executables mit allen nötigen Image-Plugins drin und fertig.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kannaum
Beiträge: 73
Registriert: 31. Januar 2010 09:57

Beitrag von kannaum »

ICh hab mir meine Idee aus dem was cih gelesen habe. meinen "Verstand" etc. zusammengewürfelt.
Habe nun mal nciht so viel Erfahrung wie du.

Du hast das bestimmt schon oft gemacht, ich mach das das erste mal und musste mir das ohne richtige Anleitung zusammenwürfeln.

Kannst du mir bitte ein bisschen genauer sagen wie das abläuft.

Habe den Text nicht zu 100% verstanden und bin jetzt noch mehr davon irritiert.

Zu einem anderen Problem noch:
Ich habe es geschafft, dass man in ein Bild ein Rechteck ziehen kann und das BIld dann auf den INhalt des Rechtecks zugeschnitten und vergrößert wird:

Code: Alles auswählen

void mousePressEvent(QMouseEvent *event) {
        x = event->x();
        y = event->y();
        modus = true;
    }

    void mouseReleaseEvent(QMouseEvent *event) {
        modus = false;
        int a = event->x();
        int b = event->y();
        w = a-x;
        h = b-y;
        newSize();
    }

    void newSize() {
        image.load(pfad);
        m_image = image.copy(x, y, w, h);
        int height = label->height();
        int width = label->width();
        m_image = m_image.scaled(width, height);
        label->clear();
        label->setPixmap(QPixmap::fromImage(m_image));

    }

Jetzt will ich aber noch, dass sich wenn man mit der gedrückten Maus über das Bild fährt (zum Rechteck-ziehen) sich die ausgewählten Pixel grau färben, damit man auch weiß was man auswählt.

Das wollte ich folgendermaßen machen:

Code: Alles auswählen

    void mouseMoveEvent(QMouseEvent *event) {
        if(modus = true) {
            QRgb value;
            value = qRgb(220, 220, 220);
            image.load(pfad);
            int a = event->x();
            int b = event->y();
            int i;
            int i2;
            for (i = 0; i <= a; i++) {
                for(i2 = 0; i <= b; i2++) {
                    image.setPixel(i, i2, value);
                }

            }
            label->setPixmap(QPixmap::fromImage(image));
        }
    }
Leider funktioniert es dann nimmer.
ICh bekomme eine Warnung:
suggest parentheses around assigment used as truth value
in der Zeile mit dem if(modus = true) {.

Wenn ich das Programm starte und in ein Bild ein Rechteck ziehe stürtzt das Programm ab und im Qt-Creator erscheinen lauter folgende Sachen:
QImage::setPixel: coordinate (0,158216) out of range

Der Rückgabewert ist -805306369, falls das noch wichtig ist.

mfg
Gesperrt