Hello all,
I have this code
Code:
public: };
and when I try to setCentralWidget with this class on QMainWindow
I get a segmentation fault.
whats more, on Windows the code DOES work, but on linux
it crash
any suggestions ?
Eli
Printable View
Hello all,
I have this code
Code:
public: };
and when I try to setCentralWidget with this class on QMainWindow
I get a segmentation fault.
whats more, on Windows the code DOES work, but on linux
it crash
any suggestions ?
Eli
Hard to say with given code, but at least QTextEdit should be the first in the inheritance list if you ever plan to add any Qt meta system stuff to your class. Could you paste backtrace from gdb by the time of crash?
this is the backtrace:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1225295584 (LWP 4130)]
0xb77e5b11 in QWidget::isAncestorOf (this=0x8097140, child=0x804ca08) at kernel/qwidget.cpp:6049
/home/elis/downloads/qt-x11-opensource-src-4.3.4/src/gui/kernel/qwidget.cpp:6049:181840:beg:0xb77e5b11
Eli
This is not a backtrace. Use the "bt" command in gdb.
ok, thanx ..
Quote:
#0 0xb77e5b11 in QWidget::isAncestorOf (this=0x8097140, child=0x804ca08) at kernel/qwidget.cpp:6049
#1 0xb77f3b02 in QWidget::setParent (this=0x8097140, parent=0x80ce47c, f=@0xbf83af20) at kernel/qwidget.cpp:7643
#2 0xb77f3f38 in QWidget::setParent (this=0x804ca08, parent=0x8097140) at kernel/qwidget.cpp:7616
#3 0xb77cfb91 in QLayout::addChildWidget (this=0x80e85a8, w=0x8097140) at kernel/qlayout.cpp:931
#4 0xb7af92f9 in QMainWindowLayout::setCentralWidget (this=0x80e85a8, widget=0x8097140) at widgets/qmainwindowlayout.cpp:1789
#5 0xb7af7080 in QMainWindow::setCentralWidget (this=0x80ce47c, widget=0x8097140) at widgets/qmainwindow.cpp:554
#6 0x0804e01b in QTMainWindowView::setCenterWidget (this=0x80ce478, view=0x8097140) at src/qt/qtmainwindowview.cpp:10
#7 0x0804d01c in MainWindow (this=0xbf83b0b0) at src/mainwindow.cpp:17
#8 0x0804e23c in runApp (app=@0xbf83b100, argc=1, argv=0xbf83b1b4) at tests/tests.cpp:34
#9 0x0804e783 in main (argc=1, argv=0xbf83b1b4) at tests/tests.cpp:49
What is runApp() and QTMainWindowView?
runApp:
QTWindowView:Code:
int runApp(QApplication& app, int argc, char** argv) { MainWindow::setViewFactory(new QTViewFactory); MainWindow mainWin; if(mainWin.evaluateArguments(argc, argv)) { mainWin.show(); return app.exec(); } return -1; }
Code:
public: void show(); void setCenterWidget(WidgetView* view); };
1. QWidget::show() is not virtual,
2. What's the contents of QTMainWindowView::setCenterWidget ?
3. What is MainWindowView?
4. I think you are lacking the Q_OBJECT macro somewhere, isAncestorOf() may be needing it, but it's hard to say that without seeing the whole code.
[QUOTE]1. QWidget::show() is not virtual [QUOTE]
I know :)
Quote:
2. What's the contents of QTMainWindowView::setCenterWidget ?
WidgetView is my parent view for all the view classes (it's empty)Code:
void QTMainWindowView::show() { } void QTMainWindowView::setCenterWidget(WidgetView* view) { }
it is pure abstract class that defines the show and setCentralWidgetQuote:
3. What is MainWindowView?
ummmm .... ?Quote:
4. I think you are lacking the Q_OBJECT macro somewhere, isAncestorOf() may be needing it, but it's hard to say that without seeing the whole code.
Good, so why do you reimplement it anyway?
Why do you cast to QWidget* in line 6? If your compiler complains without that cast then that's probably your problem - your widget is not a widget...Quote:
WidgetView is my parent view for all the view classes (it's empty)Code:
void QTMainWindowView::show() { } void QTMainWindowView::setCenterWidget(WidgetView* view) { }
Yeah... "ummmm" is right... Start by changing the inheritance order as already suggested, remove the cast to QWidget and tell us why you need the additional two layers over QWidget...Quote:
ummmm .... ?
I'm using a Abstract Factory (Pattern)
which means that I'm accessing all my views (=qt widgets) through
interfaces (=abstract classes)
that is why I need the to reimplement show()
this is also why I have two more layers
I also need the cast coz WidgetView is NOT QWidget.
Are you sure your factory can't work with QWidgets? This approach is used all over Qt's plugins.
Code:
class MyIface { public: }; Q_DECLARE_INTERFACE(...); Q_OBJECT Q_INTERFACES(...); public: };
Then you can't pass it to QMainWindow::setCentralWidget()... Simple as that...Quote:
I also need the cast coz WidgetView is NOT QWidget.
If you include QT in the Factory you loose the whole point
the point is to separate QT GUI from the program's logic
WidgetView is not a QWidget, but QTTextEdit which inherited from it IS
so I can.
this is strange, as the same code is working perfectly under Windows
I wrote a simplified program that show the problem:
Code:
#include <QtGui> class CompView { public: virtual ~CompView() {} virtual void eli() = 0; }; public: void eli() {} }; int main(int argc, char *argv[]) { QMainWindow mw; CompView* c = new Comp; mw.show(); return app.exec(); }
when I run this I also get segmentation fault
What is the point of hiding Qt architecture if you are immediately passing the pressumably non-Qt component to a Qt-expecting method?
The above works fine. Using CompView won't work because the object is aligned differently, so the compiler generates wrong offset for calling QWidget's methods.Code:
Comp* c = new Comp;
I didn't read all the posts, just the last question.
Of course you can... Qt does it with the MVC architecture, for example. There are other ways too.Quote:
can't I separate logic and gui when using Qt ?
I'm not sure what CompView is supposed to do, but it doesn't look good. Having an object inheriting from a GUI class and a class that implements app logic is not called "separating logic".
Actually, there's a word for that: "mess". In the end you'll end up with an object that exposes both things anyway.
I can't(not yet) because I still don't see the point... Are you writing a library? Or what?
Currently you are not hiding anything. You still need a QApplication object, you'll need to run QApplication::exec() eventually, etc. This is certainly not the way to go, regardless of the language used.
If you want to hide Qt, hide all of it and not a part of it - have a function(s) that will do everything starting from making sure there is a QApplication object available, through instantiating the object, showing it, manipulating it up to destroying it when it's not needed anymore. Currently you're just handling instantiation and what about the rest?
There are for instance Photoshop plugins written in Qt and they handle the situation very well, so obscuring the technology behind the interface is possible, you are just doing it the wrong way.
Here is a trivial example (not tested - and you still need QApplication::exec() somewhere):
Code:
class Iface { public: virtual void initialize() = 0; virtual void show() = 0; virtual void destroy() = 0; }; class Implementation : public Iface { public: void initialize() { } } void show() { widget->show(); } void destroy() { delete widget; } private: QMainWindow *widget; };
Plain old casting and doubble inheritance do not work as expected. Look at this line:
Try using qobject_cast or dynamic_cast:
Code:
mw.setCentralWidget( qobject_cast<QWidget*>(c) ); mw.setCentralWidget( dynamic_cast<QWidget*>(c) );
or just no cast at all:
Code:
mw.setCentralWidget( c );
And do try to put the QObject first in the double inheritance.