2016-06-09 10 views
1

Ich bin Einfügen und Entfernen von Tabs dynamisch über QSpinBox, die gut funktioniert. So füllen die gesamte Breite des Bildschirms (800px) Ich brauche die Registerkarten mit meinem eigenen event zu erweitern:Inherit benutzerdefinierte TabBar und Implementierung von resizeEvent

mainwindow.h

namespace Ui { 
class MainWindow; 
} 

class CustomTabBar : public QTabBar 
{ 
public: 
    CustomTabBar(QWidget *parent = Q_NULLPTR) 
     : QTabBar(parent) 
    { 
    } 

    void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE 
    { 
     /* Resize handler */ 
       if (e->type() == QEvent::Resize) { 
        // The width of each tab is the width of the tab widget/# of tabs. 
        resize(size().width()/count(), size().height()); 
       } 
    } 

    void tabInserted(int index) Q_DECL_OVERRIDE 
    { 
     /* New tab handler */ 
     insertTab(count(), QIcon(QString("")), QString::number(index)); 
    } 

    void tabRemoved(int index) Q_DECL_OVERRIDE 
    { 
     /* Tab removed handler */ 
     removeTab(count() - index); 
    } 
}; 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

private: 
    CustomTabBar *tabs; 
}; 

Der entsprechende Code meiner Hauptfenster sieht wie folgt aus:

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    cells = new CustomTabBar(this); 
    cells->tabInserted(1); 
// cells->installEventFilter(resizeEvent()); 
} 

void MainWindow::changeCells(int value) // Called when QSpinBox is changed 
{ 
    if (cells->count() < value) { 
     cells->tabInserted(1); 
    } 
    else if (cells->count() > value) { 
     cells->tabRemoved(1); 
    } 
} 

Wie gesagt die maximale Breite ist, auf 800 Pixel eingestellt. Das gewünschte Verhalten wäre:

  • Ein tab: 800px Breite
  • zwei Registerkarten: 400px Breite jeder
  • ...

Aber es ist egal wo ich bin Speicherzugriffsfehler eines dieser Brauch mit Veranstaltungen.

Was mache ich hier falsch?

+0

Haben Sie versucht, den Segfault zu debuggen? –

+0

Nun ja .. in meinem obigen Beispiel-Code ist es an der ersten 'cells-> tabInserted (1); Wenn ich es auskommentiere, ist es in der Klasse mainwindow.h customTabBar fehlerhaft. Anscheinend bin ich nicht in der Lage zu finden, was oder wo ich etwas vermisse .. :) –

+1

Sie scheinen Größe innerhalb der resizeEvent überschreiben aufrufen, die a) Größe der Tab-Leiste selbst, anstatt einzelne Tabs und b) führen zu unendliche Rekursion und wahrscheinlich ein Segfault. –

Antwort

0

Im Anschluss an die Kommentare habe ich versucht, das tabSizeHint Mitglied von QTabBar zu überschreiben und `es funktioniert für mich '...

Es scheint zu funktionieren, wie Sie benötigen - die Registerkarten sind so groß, dass sie die volle Fensterbreite einnehmen.

Beachten Sie, dass es auch andere Stilfaktoren geben kann, die das beeinflussen, aber ich hatte noch keine Zeit, dies zu überprüfen.

+0

Vielen Dank G.M.! Das hat den Trick mit ein paar Modifikationen geschafft. Leider kann ich noch nicht upvote. –

0

Sie werden zu disconnect(this, SIGNAL(resize()), this, SLOT(resizeEvent()) wollen, dann Wieder- connect([...]) nachdem Sie resize() genannt haben, einen Stapelüberlauf durch eine unendliche Rekursion von Resize zu vermeiden -> resizeEvent. Bearbeiten: genau wie @ G.M. sagt.

void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE 
{ 
    disconnect(this, SIGNAL(resize()), this, SLOT(resizeEvent()); 

    /* Resize handler */ 
    if (e->type() == QEvent::Resize) { 
     // The width of each tab is the width of the tab widget/# of tabs. 
     resize(size().width()/count(), size().height()); 
    } 

    connect(this, SIGNAL(resize()), this, SLOT(resizeEvent()); 
} 

Mit der richtigen Gestaltung Gedanken, Abhilfen wie diese vermieden werden können, aber ein hilfreicher Vorschlag zu geben, würden wir Ihren Anwendungsfall besser verstehen müssen.

+1

Das ist, was 'QObject :: blockSignals (bool)' ist. –

0

Da dieser Beitrag mit this one verwandt ist, kann ich sehen, dass Sie nicht verstanden haben, wie Vererbung funktioniert.

resizeEvent, tabInserted und tabRemoved aus dem Qt-Framework genannt und soll nicht direkt, daher die protected aufgerufen werden. Das ist, was insertTab und removeTab sind.

Was Sie tun, ist, wird tabInserted Aufruf, die insertTab nennt, die tabInserted nennt, die insertTab nennt, die ....

Was möchten Sie auf eine Registerkarte tun implementieren ist die Größe in Ihrem tabInserted und tabRemoved , genau wie Sie (etwas falsch) in resizeEvent getan haben.

if (e->type() == QEvent::Resize) 

ist immer wahr in resizeEvent, als dass die Bedingung für Qt ist es zu nennen.

+0

Vererbung und ich sind noch keine Freunde, das ist so wahr. Ich nahm Ihren Rat und versuchte, die "tabInserted, tabRemoved, resizeEvent" geschützt zu halten, aber was auch immer ich tat, erhielt ich den Fehler "virtual void CustomTabBar :: tabInserted/was auch immer" geschützt ist. Ich bin völlig verloren, um ehrlich zu sein .. –

+0

Geschützt bedeutet, dass Sie es aus gutem Grund nicht von außerhalb der Klasse anrufen können. In der Regel werden Sie dies für Implementierungszwecke, die sich auf der abgeleiteten Klasse unterscheiden können, wie hier passiert. Es gibt fast immer eine Möglichkeit, die geschützte Methode über eine öffentliche Methode wie 'insertTab' oder' removeTab' in diesem Szenario auszulösen. Ich würde wirklich vorschlagen, über C++ Vererbung und Qt zu lesen, bevor Sie fortfahren. –

+0

Nun, ich kenne den Unterschied zwischen "öffentlich, privat oder geschützt". Lies auch über die Vererbung und dachte, ich hätte die Idee, aber anscheinend habe ich es nicht getan und deshalb suche ich in diesem Fall nach Hilfe. Wie auch immer, ich benutzte 'cells-> insertTab (...)' in meinem Hauptfenster.cpp vorher, aber sobald 'tabInserted' geschützt war, bekam ich die oben angegebene Fehlermeldung. –

Verwandte Themen