Seite 1 von 1
update() wird nicht richtig ausgeführt
Verfasst: 20. Januar 2011 16:28
von bp
Hallo zusammen,
gibt es einen Grund warum die update Funktion nicht mehr aufgerufen wird?
Zur Beschreibung:
Ich habe ein Fenster, in dem ich ein video darstelle. jedesmal wenn ich ein bild bekommen habe, dann erstelle ich daraus ein Image und rufe die update()-Funktion auf. Das scheint so wunderbar zu funktionieren, allerdings irgendwann wird die paintEvent()-Funktion nicht mehr ordnungsgemäß durhclaufen. Soll heißen, dass zwar teile des Bildes aktualisiert werden, allerdings nicht das komplette Fenster. Wenn ich zur einer anderen Anwendung switche, und wieder zurück, dann wird auch das komplette Bild aktualisiert. Das ganze passiert natürlich wie immer ganz spontan. mal passiert das ganze innerhalb von zwei stungen, das andere mal, kann ich mehrere Stunden das Videobild darstellen.
Noch was vorneweg, ich kann hierfür kein Phonon nutzen, da ich das Videobild teilweise mit transparenten Buttons und Labels überdecken muss. Diese werden auch noch ordentlich gezeichnet, während des Fehlerfalls. Erkennbar daran, dass diese bei Betätigung das Icon ändern.
bp
Verfasst: 20. Januar 2011 17:35
von padreigh
Zeig doch mal Code, bei mir funzt Phonon nicht und ich hab zwar was mit AVCodec gebastelt aber das ist recht inperformant ...

Verfasst: 20. Januar 2011 19:51
von bp
Code: Alles auswählen
void VideoWidget::setVideoImage(mblk_t *image, int w, int h)
{
m_Mutex.lock();
if(m_pMblk != NULL)
{
freemsg(m_pMblk);
m_pMblk = NULL;
}
if(m_pImage);
{
delete m_pImage;
m_pImage = NULL;
}
if(image == NULL && w == 0 && h == 0)
{
update(0, 0, width(), height());
}
else
{
m_pMblk = image;
m_pImage = new QImage(m_pMblk->b_rptr, w, h, QImage::Format_RGB888);
if(m_pImage)
{
update(0, 0, width(), height());
}
}
m_Mutex.unlock();
}
Code: Alles auswählen
void VideoWidget::paintEvent(QPaintEvent *event)
{
m_Mutex.lock();
static int h = 0;
static int w = 0;
static int x = 0;
static int y = 0;
QPainter painter(this);
painter.eraseRect(0, 0, width(), height());
if(m_pImage != NULL)
{
{
QSize size = getDesign()->videoSize();
if(m_bFullscreen)
{
if(m_bMenu)
{
QRect t = getDesign()->geometryMenuBar();
QRect s = getDesign()->geometryStatusbar();
h = height() - t.height() - s.height();
w = h / 3 * 4;
}
else
{
h = height();
w = h / 3 * 4;
}
x = (width() / 2) - (w / 2);
y = (height() / 2) - (h / 2);
QImage image = m_pImage->scaled(w, h);
painter.drawImage(x, y, image);
}
else
{
x = (width() / 2) - (size.width() / 2);
y = (height() / 2) - (size.height() / 2);
w = width();
h = height();
if(x < 0) { x *= -1; }
if(y < 0) { y *= -1; }
painter.drawImage(QRectF(0, 0, width(), height()), *m_pImage, QRectF(0, y, size.width(), height()));
}
}
}
m_Mutex.unlock();
}
Ich kann dazu noch sagen, dass wenn der Fall auftritt, die paintEvent()-Funktion zwar aufgerufen wird, allerdings dauert es sehr lange, bis das sie wieder verlassen wird. In der zwischenzeit habe ich bestimmt so an die 15-20 neue Bilder bekommen, die dann alle verworfen werden. Aber selbst die die durchkommen werden nicht neu gezeichnet.
Verfasst: 20. Januar 2011 19:56
von padreigh
mhh ... Java? m_pImgage spricht für nen member? das hier ist nichtmal ein pointer:
Code: Alles auswählen
QImage m_pImgage = new QImage(m_pMblk->b_rptr, w, h, QImage::Format_RGB888);
kennst du
Q_FUNC_INFO ?
Code: Alles auswählen
x = (width() / 2) - (size.width() / 2); // benutzt du nie
y = (height() / 2) - (size.height() / 2);
w = width();
h = height();
if(x < 0) { x *= -1; }
if(y < 0) { y *= -1; }
painter.drawImage(QRectF(0, 0, width(), height()), *m_pImage, QRectF(0, y, size.width(), height()));
Das ist komisch ... x benutzt du nicht, wenn das Video größer ist als das widget fummelst du an den Parametern rum - was soll das bewirken / was bewirkt es?
Verfasst: 20. Januar 2011 20:10
von Christian81
Wie padreigh schon anmerkte compiliert der Code definitiv nicht.
Außerdem:
- läuft setVideoImage() in einem Thread? Ansonsten ist der Mutex überflüssig
- die ganzen Größenberechnungen und Skalierungen im paintEvent() sind nicht wirklich sehr performant - es wird immerzu alles neu berechnet aber ändern tut sich so gut wie nichts.
- warum sind w,h,x,y static?
- QPixmap ist QImage vorzuziehen (siehe auch
Doku) - paintImage konvertiert das Pixmap sowieso in ein QPixmap.
- scaled() - siehe Kommentar hier:
http://doc.trolltech.com/4.7/qpixmap.html#scaled
Verfasst: 20. Januar 2011 20:32
von bp
@padreigh:
Das ist schon eine Member, genauso wie ein Pointer. Hatte mich verschrieben.
Wenn das Videobild größer ist, als das Fenster, dann soll bloß ein ausschnitt aus dem aktuellen Bild angezeigt werden.
Fenster evtl. 756x268 Aber das Bild ist 800x600. Ist eben Kundenwunsch.
Der andere Fall skaliert ja auf die Fenstergröße.
@Christian81:
Keine Ahnung warum die static sind, hatte ich mir bestimmt mal was bei gedacht. Brauch ich allerdings nicht.
Stimmt, setVideoImage läuft in einem Thread.
QPixmap habe ich mir schon einmal angeschaut, wusste allerdings nicht so genau wie ich das benutze. Also habe ich QImage genommen, da das für mich verständlicher war. Werde mir das allerdings noch mal anschauen.
bp
Verfasst: 24. Januar 2011 11:18
von bp
Hallo.
ich habe nun ein paar weitere Tests mit meinem Programm gemacht. Dabei habe ich einiges Beobachten können. Kann aber im Moment noch so rein gar nichts damit anfangen kann.
Als erstes noch mal zur Veständnis den Aufbau des Fensters.
MainWindow(QMainWindow)
|
|--> VideoFenster
|
---> Menüleisten
Die Menüleiste ist keine Menüleiste im ursprünglichem Sinne, sondern es ist ein Fenster, welches über das VideoFenster gelegt wird. Diese beinhalten dann noch einige Buttons mit SVG-Bildern, die halbtransparent sind. Wie bereits oben beschrieben, wird nach einiger Zeit das VideoFenster icht mehr aktualisiert. Man kann es dazu zwingen, indem man in eine andere Anwendung und wieder zurück wechselt. Ebenso werden Teile des VideoFensters aktualisiert, wenn sich die Icons in den Menüleisten ändern. Die paintEvent()-Funktion wird definitiv aufgerufen. Dadurch, dass sich das Video an den Stellen aktualisiert, an denen sich der Button mit dem geänderten icon befindet, sieht es im Moment für mich so aus, als wenn Qt denken würde, dass das VideoFenster überdeckt ist, da ja nur der nicht überdeckte Teil neu gezeichnet, um mehr Performance rauszuholen.
Ich hoffe echt, dass mir einer von euch noch weitere Hinweise geben kann, an welcher Schraube ich zu drehen habe.
bp