[gelöst] CheckBox in einem TableView

Alles rund um die Programmierung mit Qt
Antworten
MiKla
Beiträge: 134
Registriert: 29. Juli 2007 15:29

[gelöst] CheckBox in einem TableView

Beitrag von MiKla »

Ich habe hier ein Problem, wo ich schon länger nach einer sauberen Lösung suche. Ich habe ein QTableView mit eigenem Model und eigenem Delegate.
In der ersten Spalte will ich permanent eine Checkbox anzeigen, die man natürlich auch schalten kann. Das anzeigen der Checkbox, permanent, ist kein Problem:

Code: Alles auswählen

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option);
     switch(index.column()){
       case 0:{         
         QStyleOptionButton newopt;
         newopt.rect = opt.rect;
         newopt.palette = opt.palette;
         newopt.palette.setColor(QPalette::ButtonText, QColor(Qt::black));
         if (index.data().toBool())
            newopt.state |= QStyle::State_On;
         QApplication::style()->drawControl(QStyle::CE_CheckBox, &newopt, painter);
...
}

QWidget *MyDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &option ,
    const QModelIndex & index ) const
{
    switch(index.column())
    {
        case 0:
        {
            QCheckBox *checkBox = new QCheckBox(parent);
            //checkBox->setLayoutDirection(Qt::RightToLeft);
            return checkBox;
        ...
        }
Das Problem ist, das wenn der Editor aufgeht die Checkbox in der Mitte erscheint, die permanente Checkbox aber linksbündig ist und somit die Checkbox "springt". Mit :

Code: Alles auswählen

newopt.direction = Qt::RightToLeft;
im paint und

Code: Alles auswählen

checkBox->setLayoutDirection(Qt::RightToLeft);
im createEditor, hab ich alles rechtsbündig und es springt nichts.
Aber ich hätte es gern zentriert! Ich habe leider keine Idee mehr, wie ich das hin bekomme! Wenn von Euch jemand eine Idee hätte wäre ich sehr dankbar!!!
Zuletzt geändert von MiKla am 28. November 2008 20:07, insgesamt 1-mal geändert.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Verwende keine QCheckBox sondern mache alles komplett selber, vor allem schau mal in den Sourcen von Qt nach.
MiKla
Beiträge: 134
Registriert: 29. Juli 2007 15:29

[gelöst] CheckBox in einem TableView

Beitrag von MiKla »

Ich habe mir sowas schon gedacht! Ich habe gehofft, dass es einen einfacheren Weg gibt.

Falls es jemanden interessiert hier meine Lösung:
im Delegate:

Code: Alles auswählen

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option);
     switch(index.column()){
       case 0:{         
		   if (index.data().toBool()){
				static bool once=false;
				QRect r(opt.rect.x()+ opt.rect.width()/2-5, opt.rect.y()+ opt.rect.height()/2-5, 10, 10);
				QPen pen, pen_save;
				if(!once){
					pen_save=painter->pen();
					once=true;
				}
				pen.setColor(Qt::gray);
				//painter->fillRect(r, opt.palette.brush(QPalette::Button));
				painter->setPen(pen);
				painter->drawRoundRect(r);
				switch(index.row())
				{
						case 0:     pen.setColor(Qt::blue);
									break;
						case 1:     pen.setColor(Qt::red);
									break;
						case 2:     pen.setColor(Qt::green);
									break;
						case 3:     pen.setColor(Qt::yellow);
									break;
						case 4:     pen.setColor(Qt::darkGreen);
									break;
						case 5:     pen.setColor(Qt::magenta);
									break;
						case 6:     pen.setColor(Qt::gray);
									break;
						case 7:     pen.setColor(Qt::cyan);
									break;
				}
				pen.setWidth(pen_save.width()+2);
				painter->setPen(pen);
				painter->drawLine(r.x()+3,r.y()+3,r.x()+r.width()-3,r.y()+r.height()-3);
				painter->drawLine(r.x()+r.width()-3,r.y()+3,r.x()+3,r.y()+r.height()-3);
		   }else{
				static bool once=false;
				QRect r(opt.rect.x()+ opt.rect.width()/2-5, opt.rect.y()+ opt.rect.height()/2-5, 10, 10);
				QPen pen, pen_save;
				if(!once){
					pen_save=painter->pen();
					once=true;
				}
				pen.setWidth(pen_save.width()+1);
				pen.setColor(Qt::gray);
				//painter->fillRect(r, opt.palette.brush(QPalette::Button));
				painter->setPen(pen);
				painter->drawRoundRect(r);
		   }
		   break;        
       }
       case 30:
       ....

    switch(index.column())
    {
        case 0:
        {
			return 0;//wichtig, damit keine CheckBox gezeichnet wird;
        }
        case 3:
        ...
im MainWindow:

Code: Alles auswählen

...
connect(tableView,	SIGNAL(clicked ( const QModelIndex &)), this, SLOT(tableViewClicked(const QModelIndex &)));
...

void QtTest01::tableViewClicked(const QModelIndex &index){
	if (index.isValid()){
		if (index.column()== 0)
			model->setData(index, !index.data().toBool());
	}
}
Damit funktioniert es wie ich es mir vorgestellt habe!
Vielen Dank für die Anregung!
MiKla
Beiträge: 134
Registriert: 29. Juli 2007 15:29

[gelöst] CheckBox in einem TableView

Beitrag von MiKla »

Die obere Version funktioniert zwar aber so richtig gefallen hat es mir nicht. Also habe ich heute noch mal im Qt Sourcecode gesucht und bin fündig geworden. Für die, die es interessiert, hier die neue Version:

Code: Alles auswählen

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
     QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option);
     QStyleOptionButton opt1;

     switch (index.column())
     {
       case 0:
       {
            switch (index.row())
            {
                    case 0:  opt1.palette.setColor(QPalette::Text, Qt::blue);
                                break;
                    case 1:  opt1.palette.setColor(QPalette::Text, Qt::red);
                                break;
                    case 2:  opt1.palette.setColor(QPalette::Text, Qt::green);
                                break;
                    case 3:  opt1.palette.setColor(QPalette::Text, Qt::yellow);
                                break;
                    case 4:  opt1.palette.setColor(QPalette::Text, Qt::darkGreen);
                                break;
                    case 5:  opt1.palette.setColor(QPalette::Text, Qt::magenta);
                                break;
                    case 6:  opt1.palette.setColor(QPalette::Text, Qt::gray);
                                break;
                    case 7:  opt1.palette.setColor(QPalette::Text, Qt::cyan);
                                break;
            }
            opt1.state |= index.data().toBool() ? QStyle::State_On : QStyle::State_Off;
            const QStyle *style = QApplication::style();
            const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt);
            const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt);
            opt1.rect = QRect(opt.rect.x()+ opt.rect.width()/2-indicatorWidth/2, 
                              opt.rect.y()+ opt.rect.height()/2-indicatorHeight/2, 
                              indicatorWidth, indicatorHeight);
            style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt1, painter);
            break;
       }
       case 3:
       ...
Der Rest ist gleich geblieben. Diese Version gefällt mir richtig gut :lol:

Gruß Micha
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag von gk_17 »

Moin,

ist mein erster Post hier, also nochmal hallo an alle!

Ich habe wie hier beschrieben eine Checkbox über die paint-Methode einer von QItemDelegate abgeleiteten Klasse in ein QTableView eingefügt.

Wenn ich nun mit der Maus einzelne oder alle Felder der Tabelle auswähle/markiere, werden genau die Felder mit der Checkbox nicht blau hinterlegt. Das irritiert und ich würde es gerne hinkriegen, habe nur keine Ahnung, in welcher Richtung ich suchen muss. Hat jemand einen Hinweis?

Danke,
Gernot
Antworten