Qt 4.7+Xlib crash on QWidget::winId() method - qt

Sorry for my english, but I have the next problem. I am writing a window manager using Qt 4.7 and Xlib. I have class Manager that inherits QApplication and reimplemented method X11EventFilter in it. In X11EventFilter method I catch necessary events from XServer. When I receive MapRequest event, I catch appearing of new window and reparent it to my own widget. And when I create that widget and call QWidget::show() or QWidget::winId() methods, program crashes. What is the problem?
Here is a method where widget is creating. I wonder, when this function calls few times on start of program, everything is OK.
void Manager::createClientWindow(Qt::HANDLE pWinID)
{
QMWindowWidget *lWindowWidget = new QMWindowWidget(pWinID);
/*some code*/
lWindowWidget->show();//crash is here
Qt::HANDLE widgetId = lWindowWidget->winId();//and here
/*some code*/
}
Here is a x11EventFilter method where createClientWindow function is called
bool Manager::x11EventFilter(XEvent *pEvent)
{
switch(pEvent.type)
{
/*some code*/
case MapRequest:
{
Qt::HANDLE lWindow = pEvent->xmaprequest.window;
QMWindowWidget* lWidget = findWidget(lWindow);
if (!lWidget)
{
lWidget = dynamic_cast<QMWindowWidget*>(QWidget::find(lWindow));
}
if (lWidget)
{
XMapWindow(QX11Info::display(), lWindow);
lWidget->show();
XRaiseWindow(QX11Info::display(), lWidget->winId());
return true;
}
else
{
createClientWindow(lWindow);//here is where function is called
return true;
}
}
break;
/*some code*/
} //switch
return false;
}

The problem most likely resides in the code represented by /*some code*/. Since it is not known what's there, it's very difficult to pinpoint the exact cause of the problem. If you cannot show all the code, you will have to track the problem down yourself.
You will need to build in debug mode and link with the debug version of Qt. Then when the crash happens, look at the exact line of Qt source and analyse the broken data structures with a debugger and try to figure out why they are broken. Maybe set a watchpoint on a problematic variable and find out what code writes an invalid value there.
In order to program in low level languages such as C and C++ one has to learn how to do this stuff.

Problem is resolved! I paste this two strings before QApplication::exec()
XClearWindow(QX11Info::display(), QX11Info::appRootWindow());
XSync(QX11Info::display(), false);

Related

Qt - start process with click event and stop it again with the second click event

I found time to investigate a bit into QT, and it is very interesting for me. However, right now I am encountering a problem that I am not aware about how to solve it. My aim is actually simple. I have a QCheckBox that I want to activate. If it is activated, I am starting a process (I am opening a file, reading it, taking some values out and change different labels accordingly). This process is repeated until the user is deactivating the QCheckBox. Some small code example to get a better idea of what I am going to do.
void Analyzer::on_actualTemperature_stateChanged(int arg1)
{
// Read data and change labels
if (arg1 != 0)
{
qDebug() << "Start data analysis";
// Infinity loop to get the data and display it
while true
{
// Open file and extract data
const actualTemperature = getData();
// Change any label or do something with the data
ui->anyLabel->setText(actualTemperature);
// Some break
QThread::sleep(1);
// Leave the loop if user deactivate the QCheckBox
// Something like on_actualTemperature_stateChange == 0
}
}
// Stop reading the data
else
{
qDebug() << "Stop data analysis";
}
}
It is obvious that after activating the QCheckBox, the loop will not finish at all and the GUI will not recognize anything anymore. Hence, I guess I have to start some new thread and have to kill it. However, I have no idea how to proceed here. An idea would be:
void Analyzer::on_actualTemperature_stateChanged(int arg1)
{
// Read data and change labels
if (arg1 != 0)
{
// Start reading the file and updating the label using some other thread
startThread(XY);
}
// Stop reading the data
else
{
// Kill thread 1234
killThread(XY);
}
}
Any hint is warmly welcomed and I hope this question is not too basic for you. Thank you for reading, Tobi.
I think killing a running thread is not a decent behavior. Let's be gentle to our threads with a loop control variable. In this example it named keepLoop. Set keepLoop when checkbox checked. Then start thread if it is not running. We are using QtConcurrent::run, and monitoring it by a QFuture in this case.
connect(ui->checkBox, &QCheckBox::toggled,
[&](const bool checked) {
analyzer->keepLoop = checked;
if (checked && !future.isRunning())
future = QtConcurrent::run(analyzer, &Analyzer::on_actualTemperature_stateChanged);
}
);
Don't call user interface slots directly, instead connect them to signals. Connections will be queued connection when signals emitted from another thread. It means slots will be called in event loop of main thread and changes will be shown when the next frame painted.
connect(analyzer, &Analyzer::temperatureCalculated, ui->anyLabel, &QLabel::setText);
Our asynchronous function does not forced to die immediately when user toggle checkbox. Instead we letting it to finish the iteration it already on halfway through.
Analyzer::on_actualTemperature_stateChanged() {
while (keepLoop) {
// Open file and extract data
const QString& actualTemperature = getData();
// send data
emit temperatureCalculated(actualTemperature);
}
}
You can use atomic bool if you want a more precise loop control.
Bonus:
If you don't want to mess with threads, you can avoid GUI freezing by using QTimer to run your loop periodically in main thread.

I can't catch an Error

I can't catch the thrown error in my simplified code below. Why is that?
According to requirements of the stackoverflow I must insert some more info but this example is very simple. Can you help me with this example?
package com.myserver {
public class ReturnInfo extends Sprite {
public function ReturnInfo(urlParamsArr:Array) {
try {
var client:HttpClient = new HttpClient();
var uri:URI = new URI("http://valid-url.com/aaa.php");
client.listener.onData = function(event:HttpDataEvent):void {
throw new Error();
};
client.listener.onError = function(event:IOErrorEvent):void {
trace("error");
};
client.postFormData(uri, variables);
}
catch (e:Error){
trace("Error was caught.");
}
}
} //class
} //package
I tried also:
try {
new ReturnInfo(urlParamsArr);
}
catch(e:Error){
trace("caught error");
}
It didn't work either.
The code does not work because the code that throws error is executed later, so you need to use try-catch in the client.listener.onData handler. That handler I assume is called sometimes later so there when you parse or handle the data,make sure to catch/handle the errors
Adding on to what Simion said, the problem is method closure. In order for an exception to be caught somewhere in the "food chain" the catch needs to be in the stack - you will know what is in the current stack by getStackTrace(). In this example, there is no stack pointer that sits at the constructor (or any method) like there is one for client.listener.onData - which is why the postFormData will execute. When the event is triggered it's stack pointer goes back to the origination point of what actually started the event trigger in the first place (not the method that declared it). This is also why the 2nd attempt was unsuccessful.
Add on to the fact that the FP executes discrete chunks in frames (think of this like a heap), anything that executes in the scope of the dispatchEvent will generally have a very small or no stack at all (eg the first stack pointer is usually the dispatcher itself - not a method that actually called it).
try-catch is best attempted within the same scope of a method.
A pseudo example:
function getOrCreateWidget():Widget {
var a:Widget;
try {
a = getWidet();
}
catch(e:TypeError) {
a = createNewWidget();
}
//finally can be debatable - most of us leave it off
//bc it executes anyway just as it would in the function scope.
finally {
a.property = 'foo';
}
return a;
}
If this isn't possible - a last ditch effort is to attach a listener to the loaderInfo.uncaughtErrorEvents. Generally associating this with the systemManager is the best option because the SM knows about every branch of the display tree right down to the root stage. It's neither good practice nor practical to assign all deviations in this method because a lot of context to the programmer is usually lost. It's more an "oh S#!) sorry user, our app just verped."

Enqueue in Phonon no longer working

After a recent software update to the phonon libraries, I've noticed that a media playing application that I wrote is no longer able to loop tracks. The code in question is below. The first track is set, and once it nears completion it is set to play again.
void Alarm::Start(bool useCustom)
{
if(useCustom)
{
media->setCurrentSource(Phonon::MediaSource(this->_CustPath));
this->_UsingCustomPath=true;
}else{
FileIO::ExtractAudio();
media->setCurrentSource(Phonon::MediaSource(this->_DefaultPath));
this->_UsingCustomPath=false;
}
media->play();
connect(media,SIGNAL(aboutToFinish()),this,SLOT(RepeatAllTheThings()));
this->_isPlaying=true;
}
void Alarm::RepeatAllTheThings()
{
if(this->_UsingCustomPath)
{
media->enqueue(this->_CustPath);
}else{
media->enqueue(this->_DefaultPath);
}
}
After running through the debugger a few times I noticed this message:
"Ignoring source as no aboutToFinish handling is in progress"
A quick google search doesn't tell much about this message. It looks like a check for a private variable (that I dont have access to) has been added (a diff of the file)
Does anyone know if I just discovered a new bug in phonon, or am I some how using the enqueue method incorrectly?
EDIT:
The code above only fails about 1/2 the time. Very confused. Currently running phonon-gstreamer 4.6.3
Solved with this work-around:
media->play();
connect(media,SIGNAL(finished()),this,SLOT(RepeatAllTheThings()));
void Alarm::RepeatAllTheThings()
{
if(this->_UsingCustomPath)
{
media->setCurrentSource(Phonon::MediaSource(this->_CustPath));
}else{
media->setCurrentSource(Phonon::MediaSource(this->_DefaultPath));
}
media->play();
}

OpenCV and (not) returning IplImages, when is it okay, when not?

is it okay to do something like this, the code snippet is of course not complete, just to show what I mean:
void draw(IplImage* image){
cvLine(image,cvPoint(20,20),cvPoint(100,100),cvScalar(0,0,255),1);}
int main(){
cvNamedWindow("preview",CV_WINDOW_AUTOSIZE);
IplImage* image;
image=cvCreateImage(cvSize(480,360),8,3);
while(true){
draw(image);
cvShowImage("preview",image);
int ops=cvWaitKey(10)
if ops!=-1 break;}
cvReleaseImage(&image);cvDestroyWindow("preview");return 0;
}
or will it cause problems if I don't return the IplImage like this:
IplImage* draw(IplImage* image){
cvLine(image,cvPoint(20,20),cvPoint(100,100),cvScalar(0,0,255),1);return image;}
well, the reason why I'm asking is that sometimes it works if I don't return the IplImage. However it may also happen that I'll receive some sort of NULL pointer error message in other cases. If for example I release the image in the function and then create it anew right after that, still being in that function, a crash may happen.
You don't need to return anything, but you definitely need to check for failures!
The problem is that you are not coding safely. You are never checking for failures when calling OpenCV functions, which may result in draw() receiving a NULL pointer as parameter, and that might cause a crash or some other weird behavior along the way.
The first thing you should do is start coding defensively:
IplImage* image = cvCreateImage(cvSize(480,360),8,3);
if (!image)
{
// print error and quit
}
and it wouldn't hurt to add a safety check inside your function:
void draw(IplImage* image)
{
if (!image)
{
// print error
return;
}
cvLine(image,cvPoint(20,20),cvPoint(100,100),cvScalar(0,0,255),1);
}

Flex-IFrame Comm Test Not Working

I'm trying to get the IFrameCommTest example (from the Flex-IFrame site) to work in Flex 4, and, while the IFrame itself works, the communication does not. In particular, I need to get the included HTML page to call functions from the flex app (I already have a way to get the Flex app to talk to the HTML).
I've exported the project to facilitate your help.
The problem, I suspect, is that the "parent.FABridge" doesn't exist. My guess is that something in flex4 changed with regard to how things are located in the DOM.
(This post is related to the earlier post about FABridge.
I thought this would be a clearer example of the problem. )
Thanks,
Brian
I've solved this my own self :D
The difference over the mechanism above is in the getFlexApp() function, and it provides a way to, well, get the flex object. Once the objecty it gotten, I just call the EIButtonClicked() function, and pass a value to it.
function getFlexApp(appName) {
if (navigator.appName.indexOf ("Microsoft") !=-1) {
return window.top[appName];
} else {
return window.top.document[appName];
}
}
function callFlexFunction() {
var sTxt ;
sTxt = document.getElementById('txt1').value;
alert('HTML/Javascript wants to tell you about ' + sTxt);
getFlexApp('iframeCommTest').EIButtonClicked(sTxt) ;
}
Meanwhile, the flex side has an external interface callback established. You can see that the "EIButtonClicked" referenced in the JS above is matched by the label for the callback in the AS below.
/**
* When the button is clicked.
*/
public function onEIButtonClicked(data:String):void {
Alert.show("Flash wants to tell you about " + data);
}
protected function application1_creationCompleteHandler():void {
// TODO Auto-generated method stub
if (ExternalInterface.available) {
ExternalInterface.addCallback("EIButtonClicked", onEIButtonClicked);
}
}

Resources