Problem mit QFrame

Alles rund um die Programmierung mit Qt
Antworten
Headcracker
Beiträge: 3
Registriert: 16. Februar 2011 17:58

Problem mit QFrame

Beitrag von Headcracker »

Hallo!

Ich habe folgende Aufgabenstellung:

Ein QFrame soll ein einzelnes Feld darstellen, in dem eine Zahl eingetragen werden soll. Bei einem Mausklick auf den Frame soll dieser den Fokus erhalten und dabei einen Rahmen gezeichnet bekommen (um zu erkennen, dass er fokussiert ist).

Sobald also der Fokus auf dem Frame liegt, soll man mit der Tastatur eine Zahl eingeben können.

Ich bin soweit, dass ich den Frame habe und zunächst über das paintEvent mit einer 0 beschrifte (sodass also gleich bei Programmstart eine 0 im Frame steht).

An dieser Stelle komme ich nun nicht weiter.
Vor allem, da QFrame kein click-Event hat und man das (soweit ich weiß) über ein Mouse-Event implementieren muss.

Wie genau kann ich also mit einem Mausklick den Fokus auf den Frame setzen und dabei einen Rahmen im Frame zeichnen lassen?

Das ist meine Sudokucell.h:

Code: Alles auswählen

#pragma once

#include <QtGui>

class Sudokucell : public QFrame
{
    Q_OBJECT;

public:
    Sudokucell(QWidget *parent=0) : QFrame(parent), _isFilled(false), _prefilled(false), _solution(1), _currentValue(1){}
public slots:

private:
    bool _isFilled;
    bool _prefilled;
    int _solution;
    int _currentValue;
protected:
    void paintEvent(QPaintEvent *event);
};
Das ist die Sudokucell.cpp:

Code: Alles auswählen

#include "sudokucell.h"

void Sudokucell::paintEvent(QPaintEvent*)
{
    QPainter painter(this);

    painter.drawText(rect(), "0");
}
Und hier noch meine main.cpp:

Code: Alles auswählen

#include "sudokucell.h"

int main(int argc,char *argv[])
{
    QApplication app(argc,argv);

    Sudokucell *cell = new Sudokucell();

    cell->show();
    cell->resize(100,100);
    cell->setFont(QFont("Arial", 70));
    cell->setWindowTitle("Cell");

    //QObject::connect(X,SIGNAL(X()),cell,SLOT(setFocus()));

    app.exec();

    return 0;
}
Die X im Kommentar kennzeichnen einfach nur, dass ich nicht weiß, welches Signal ich da nehmen muss.
Headcracker
Beiträge: 3
Registriert: 16. Februar 2011 17:58

Beitrag von Headcracker »

ok, hat sich teilweise erledigt. Ein Kollege hat mir einen HInweis gegeben.

Brauch ja gar keine SIGNAL-SLOT-Verbindung, ich brauch ja nur ne protected Methode, mit der ich das mousePressEvent überschreibe, was im QFrame schon implementiert ist.

In der Header-Datei hab ich bei den protected Methoden also noch

Code: Alles auswählen

void mousePressEvent(QMouseEvent* event);
hinzugefügt.

Und in der cpp hab ich die dann so

Code: Alles auswählen

void Sudokucell::mousePressEvent(QMouseEvent*)
{
    this->setFocus(Qt::MouseFocusReason);
}
implementiert.

Und was in meinem 1. Post in der main.cpp noch als Kommentar gekennzeichnet war, hab ich jetzt ganz rausgeschmissen.


Aber wie ich einen Rahmen in den Frame zeichne, weiß ich leider trotzdem noch nicht. :(
Hoffe, einer von euch kann mir helfen.
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Was spricht dagegen ein kurzes QLineEdit zu nehmen? Du könntest das in ein QFrame packen. Rahmen bekommt man übrigens mittels entsprechender Membermethoden, ich verweise mal auf die API http://doc.qt.nokia.com/latest/qframe.html und

Code: Alles auswählen

void 	setFrameShadow ( Shadow )
void 	setFrameShape ( Shape )
void 	setFrameStyle ( int style )
Zuletzt geändert von padreigh am 16. Februar 2011 19:59, insgesamt 1-mal geändert.
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Was ist denn der Unterschied zwischen einem click-Event und einem mousePressEvent?

Und wenn man im paintEvent das Event zusätzlich noch an die abgeleitete Klasse übergibt, bekommt man auch einen Rahmen.
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Rechtsklick oder Linksklick .. ich find rechts hübscher ...

Code: Alles auswählen

#ifndef MYFRAMEDNUMBERINPUTWIDGET_H
#define MYFRAMEDNUMBERINPUTWIDGET_H

#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
#include <QFontMetrics>
#include <QInputDialog>
#include <QMouseEvent>
#include <QDialog>
#include <QToolButton>

class MyFramedNumberInputWidget : public QFrame
{
    Q_OBJECT

    QLabel * m_lab;
public:
    MyFramedNumberInputWidget(QWidget * parent = 0, Qt::WindowFlags f = 0) :
            QFrame(parent, f), m_lab(0)
    {
        setFrameStyle(QFrame::Box|QFrame::Raised);

        QHBoxLayout * hbl = new QHBoxLayout(this);

        m_lab = new QLabel(this);
        {
            QFont f = m_lab->font();
            f.setPointSize(14);
            m_lab->setFont(f);

            QFontMetrics fm(m_lab->font());
            const int w = fm.width("99");
            m_lab->setMaximumSize(w,w);
            m_lab->setAlignment(Qt::AlignCenter);
            setMaximumSize(m_lab->size()*2);
            hbl->addWidget(m_lab);
        }

        setMouseTracking(true);
        connect (this,SIGNAL(newValue(int)),this,SLOT(updateLabel(int)));
    }

signals:
    void        newValue (int);

protected:
    void mousePressEvent(QMouseEvent *event)
    {
        if (event->button() == Qt::LeftButton)
            emit newValue(getNumber());
        else emit newValue(getNumber2());
    }

private slots:
    void updateLabel(int i)
    {
        if (i == -1) m_lab->clear();
        else m_lab->setNum(i);
    }

private:
    int getNumber()
    {
        bool ok = false;
        int ret = QInputDialog::getInt(this,tr("Enter number"),tr("Number:"),1,1,9,1,&ok);
        if (!ok)
            return -1;
        else
            return ret;
    }

    int getNumber2()
    {
        static QDialog * d = 0;
        

        if (d == 0)
        {
            d = new QDialog(this);
            QGridLayout * grid = new QGridLayout(d);
            grid->setSpacing(0);

            for(int i=1;i<10;++i)
            {
                QToolButton * tb = new QToolButton(d);
                tb->setText(QString::number(i));
                tb->setObjectName(tb->text());
                tb->setCheckable(true);
                tb->setChecked(false);
                grid->addWidget(tb,(i-1)/3,(i-1)%3);
                connect(tb,SIGNAL(clicked()),d,SLOT(accept()));
                if (i==9)
                {
                    tb = new QToolButton(d);
                    tb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
                    tb->setText(tr("Clear"));
                    tb->setObjectName(tb->text());
                    grid->addWidget(tb, grid->rowCount(),0,1,3);
                    connect(tb,SIGNAL(clicked()),d,SLOT(reject()));
                }
            }
        }

        if (d->exec() == QDialog::Rejected)
        {
            return -1;
        }
        else
        {
            foreach (QToolButton *tb, d->findChildren<QToolButton*>())
            {
                if (tb->isChecked())
                {
                    tb->setChecked(false);
                    return tb->text().toInt();
                }
            }
        }
        return -1;
    }
};
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
Headcracker
Beiträge: 3
Registriert: 16. Februar 2011 17:58

Beitrag von Headcracker »

Danke für eure Hilfe!

Ich habe die Aufgabenstellung jetzt umsetzen können. Zwar anders als ihr vorgeschlagen habt, aber trotzdem vielen Dank für eure Unterstützung! :)
Antworten