Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-interest Archive, February 2007
Is there something wrong in this Qt's Faq ?


Message 1 in thread

Please refer to this Faq, regarding the conversion of QString to char *
http://www.trolltech.com/developer/knowledgebase/faq.2007-01-30.9032238253/

The Faq says to use toLatin1().data().

toLatin1() creates a temporary QByteArray which gets destroyed the
next moment ? So how correct is the answer there ?

-- 
 [ signature omitted ] 

Message 2 in thread

Hello,

why should this be wrong? It is right that the QByteArray is destroyed 
after the toLatin1() call but the destructor will be called AFTER the 
line. Therefore the data() function will be called on a valid object.

Regards,
Falko


--- Original-Nachricht ---
Absender: Sunil Thaha
Datum: 01.02.2007 12:26
> Please refer to this Faq, regarding the conversion of QString to char *
> http://www.trolltech.com/developer/knowledgebase/faq.2007-01-30.9032238253/ 
>
>
> The Faq says to use toLatin1().data().
>
> toLatin1() creates a temporary QByteArray which gets destroyed the
> next moment ? So how correct is the answer there ?

--
 [ signature omitted ] 

Message 3 in thread

> Hello,
>
> why should this be wrong? It is right that the QByteArray is destroyed
> after the toLatin1() call but the destructor will be called AFTER the
> line. Therefore the data() function will be called on a valid object.


Pardon me if am wrong. But the data() returns a  char*  and I believe the
char*  points to internal datamember QByteArray that was created Temporily.
And that just got destroyed. So the OS is free to take that memory anytime
it like. My guess is that after sometime it contenst would be overwritten.
Is this right ? or Am I missing my basics ?

Regards
Sunil Thaha

Message 4 in thread

You are correct, the char * returned by QByteArray::data() is only valid
for the life of the QByteArray object, which as you've correctly pointed
out may be short lived.  Depending on what you are trying to do, you
have a couple of options.
 
You could declare your own char * and copy the data into that, so you
still have the data around after the QByteArray disappears:
  QString myQString;
  // fill myQString with some data
  char * myData = new char[myQString.length()];
  strcpy(myData, myQString.toLatin1().data(), myQString.length());
  // do whatever you need to do with myData
  delete [] myData;
 
Or you could declare your own QByteArray and keep that around, so now
the QByteArray isn't short lived:
  QString myQString;
  // fill myQString with some data
  QByteArray ba;
  ba = myQString.toLatin1();
  // now do whatever you need to do with ba
 
These solutions are only needed though if you need to keep the data
around in something like a char *.  There is nothing wrong with doing
something like:
  QString myQString;
  // fill myQString with some data
  sprintf("Here's my string: %s", myQString.toLatin1().data());
Because the char * returned by data() is valid until the ';'
 
Sean


________________________________

	From: Sunil Thaha [mailto:sunil.thaha@xxxxxxxxx] 
	Sent: Thursday, February 01, 2007 7:04 AM
	To: qt-interest@xxxxxxxxxxxxx
	Cc: qt-interest@xxxxxxxxxxxxx >> QT Interest List
	Subject: Re: Is there something wrong in this Qt's Faq ?
	
	


		Hello,
		
		why should this be wrong? It is right that the
QByteArray is destroyed 
		after the toLatin1() call but the destructor will be
called AFTER the
		line. Therefore the data() function will be called on a
valid object.


	Pardon me if am wrong. But the data() returns a  char*  and I
believe the  char*  points to internal datamember QByteArray that was
created Temporily. And that just got destroyed. So the OS is free to
take that memory anytime it like. My guess is that after sometime it
contenst would be overwritten. Is this right ? or Am I missing my basics
? 
	

	Regards 
	Sunil Thaha
	
	


Message 5 in thread

Hi,

I hope to make a QTabWidget which could have two types of tabs: local 
and global.
By “global” means when I have several instance of the QTabWidget, the 
global tab page always keeps consistence (all parameter setting on this 
tab appears the same) across every instance.

In following practice, I declared one global tab and used it to 
constructed three QTabWidget.
Result is the last one got both tabs, but the first two got the local 
one only.
Do you have a solution/suggestion how to make global tab in QTabWidget?

Thanks in advance.
Lingfa

//=================================================================================================

GlobalTab::GlobalTab(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(new QLabel("Server Name"));
layout->addWidget(new QLineEdit("dew"));
this->setLayout(layout);
}

//=================================================================================================

LocalTab::LocalTab(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(new QLabel("Width"));
layout->addWidget(new QLineEdit("123"));
this->setLayout(layout);
}

//=================================================================================================

MyTabWidget::MyTabWidget(GlobalTab *globalTab, QWidget *parent)
: QTabWidget(parent)
{
this->addTab(new LocalTab(this),"Local");
this->addTab(globalTab,"Global");
}

//=================================================================================================

MyTabWidgetTest::MyTabWidgetTest(QWidget *parent)
{
GlobalTab *globalTab = new GlobalTab();
tabWidget1 = new MyTabWidget(globalTab); // local only
tabWidget2 = new MyTabWidget(globalTab); // local only
tabWidget3 = new MyTabWidget(globalTab); // local + global

tabWidget1->show();
tabWidget2->show();
tabWidget3->show();
}


--
 [ signature omitted ] 

Message 6 in thread

lingfa wrote:

> Hi,
>
> I hope to make a QTabWidget which could have two types of tabs: local 
> and global.
> By “global” means when I have several instance of the QTabWidget, the 
> global tab page always keeps consistence (all parameter setting on 
> this tab appears the same) across every instance.
>
> In following practice, I declared one global tab and used it to 
> constructed three QTabWidget.
> Result is the last one got both tabs, but the first two got the local 
> one only.
> Do you have a solution/suggestion how to make global tab in QTabWidget?
>
> Thanks in advance.
> Lingfa
>
> //================================================================================================= 
>
>
> GlobalTab::GlobalTab(QWidget *parent)
> : QWidget(parent)
> {
> QHBoxLayout *layout = new QHBoxLayout;
> layout->addWidget(new QLabel("Server Name"));
> layout->addWidget(new QLineEdit("dew"));
> this->setLayout(layout);
> }
>
> //================================================================================================= 
>
>
> LocalTab::LocalTab(QWidget *parent)
> : QWidget(parent)
> {
> QHBoxLayout *layout = new QHBoxLayout;
> layout->addWidget(new QLabel("Width"));
> layout->addWidget(new QLineEdit("123"));
> this->setLayout(layout);
> }
>
> //================================================================================================= 
>
>
> MyTabWidget::MyTabWidget(GlobalTab *globalTab, QWidget *parent)
> : QTabWidget(parent)
> {
> this->addTab(new LocalTab(this),"Local");
> this->addTab(globalTab,"Global");
> }
>
> //================================================================================================= 
>
>
> MyTabWidgetTest::MyTabWidgetTest(QWidget *parent)
> {
> GlobalTab *globalTab = new GlobalTab();
> tabWidget1 = new MyTabWidget(globalTab); // local only
> tabWidget2 = new MyTabWidget(globalTab); // local only
> tabWidget3 = new MyTabWidget(globalTab); // local + global
>
> tabWidget1->show();
> tabWidget2->show();
> tabWidget3->show();
> }

If there is no way to make a global tab which allows QTabWidget to share
(I guess not, because no one answer the question since it was posted on 
2/1/07),
let’s make a detour --- change it into a new question: one set of data 
with synchronized multiple views.
In this example,
    serverName is the data.
    QLineEdit is the view, which appears in every instance of QTabWidget.
    Synchronization means when you are editing one meanwhile you see all 
the others are editing.
Here is one practice: change one view update all views.

Do you have a better solution/suggestion?

Thanks,
Lingfa

//==========================================

class GlobalTab : public QWidget
{
        Q_OBJECT
public:
        GlobalTab(QWidget *parent=0);
private:
        QString m_serverName;
        static QList<QLineEdit *> serverNames;
private slots:
        void serverNameChanged(const QString &);
};

//==========================================

QList<QLineEdit *> GlobalTab::serverNames;
GlobalTab::GlobalTab(QWidget *parent)
: QWidget(parent)
, m_serverName("dew")
{
        serverNames << new QLineEdit(m_serverName);
        connect(serverNames.last(), SIGNAL(textChanged(const QString &)),
                this, SLOT(serverNameChanged(const QString &)));

        QHBoxLayout *layout = new QHBoxLayout;
        layout->addWidget(new QLabel("Server Name"));
        layout->addWidget(serverNames.last());
        this->setLayout(layout);
}
void GlobalTab::serverNameChanged(const QString &text)
{
        foreach(QLineEdit *lineEdit,  serverNames)
                lineEdit->setText(text); // change one update all.
}

//==========================================

MyTabWidget::MyTabWidget(QWidget *parent)
: QTabWidget(parent)
{
        addTab(new LocalTab(this),"Local");
        addTab(new GlobalTab(this),"Global");
}

//==========================================

MyTabWidgetTest::MyTabWidgetTest(QWidget *parent)
{
        tabWidget1 = new MyTabWidget;
        tabWidget2 = new MyTabWidget;
        tabWidget3 = new MyTabWidget;

        tabWidget1->show();
        tabWidget2->show();
        tabWidget3->show();
}


--
 [ signature omitted ] 

Message 7 in thread

On Thu, February 1, 2007 13:03, Sunil Thaha wrote:
> Pardon me if am wrong. But the data() returns a  char*  and I believe the
> char*  points to internal datamember QByteArray that was created
> Temporily.
> And that just got destroyed. So the OS is free to take that memory anytime
> it like. My guess is that after sometime it contenst would be overwritten.
> Is this right ? or Am I missing my basics ?

It's not exactly basics. But you can try this out easily with the code below.

You will see that the temporary objects used in a line of code are created
before the outer function of the line (in this case all the cout<<
operators) is called and destroyed AFTER the outer function finishes. So
the temporary object is still valid while its data element is used.


     Konrad


----code----

#include <iostream>
using namespace std;

#include <string.h>

class MyTemp{
  public:
    MyTemp(const char*s){
        tmp=new char[strlen(s)+1];
        strcpy(tmp,s);
        cout<<"create\n";
    }
    ~MyTemp(){
        delete tmp;
        cout<<"destroy\n";
    }
    char*get(){
        cout<<"getting\n";
        return tmp;
    }
  private:
    char*tmp;
};


main()
{
    cout<<"long before\n";
    cout<<"before\n"<<MyTemp("hello\n").get()<<"after\n";
    cout<<"long after\n";
}

---end of code---

--
 [ signature omitted ] 

Message 8 in thread

Thanks a lot for that code. It clears all my doubts !!
Thanks once

Message 9 in thread

Von: Falko Buttler <falko.buttler@xxxxxxxx>
> Hello,
> 
> why should this be wrong? It is right that the QByteArray is destroyed 
> after the toLatin1() call but the destructor will be called AFTER the 
> line. Therefore the data() function will be called on a valid object.
> 
But the second sentence is wrong:
"To convert a QString to a char* you can do the following:"
should be
"To convert a char* to a QString you can do the following:"

Or is my english that bad that I don't understand the sentence correct?

Christian
-- 
 [ signature omitted ] 

Message 10 in thread

>
> But the second sentence is wrong:
> "To convert a QString to a char* you can do the following:"
> should be
> "To convert a char* to a QString you can do the following:"
>
> Or is my english that bad that I don't understand the sentence correct?


You are right there. But I am not pointing at that. I was pointing at the
conversion of QString to char*.
Please refer to this article which explains what is wrong with that approach
http://wiki.qtcentre.org/index.php?title=QString

Best regards
Sunil Thaha

Message 11 in thread

Von: "Sunil Thaha" <sunil.thaha@xxxxxxxxx>
> >
> > But the second sentence is wrong:
> > "To convert a QString to a char* you can do the following:"
> > should be
> > "To convert a char* to a QString you can do the following:"
> >
> > Or is my english that bad that I don't understand the sentence correct?
> 
> 
> You are right there. But I am not pointing at that. I was pointing at the
> conversion of QString to char*.
> Please refer to this article which explains what is wrong with that
> approach
> http://wiki.qtcentre.org/index.php?title=QString
> 
I know this discussion and would say that the faq is maybe confusing for beginners who are not aware of this problem. But the faq entry is correct - you get a char* the way it's described, *but* it does not live long :)

Maybe you should write to qt-bugs so they can fix the faq entry.

Christian

-- 
 [ signature omitted ] 

Message 12 in thread

>> But the second sentence is wrong:
>> "To convert a QString to a char* you can do the following:" 
>> should be
>> "To convert a char* to a QString you can do the following:"
>>	
>> Or is my english that bad that I don't understand the 
>> sentence correct?

> You are right there. But I am not pointing at that. I was 
> pointing at the conversion of QString to char*. 
> Please refer to this article which explains what is wrong with 
> that approach http://wiki.qtcentre.org/index.php?title=QString
	
Ha, this site basically repeats my previous email!  I'd say this site
says it exactly how Qt's own docs should say it.  It gives the developer
a clear view of how to get a char * out of a QString and how he should
go about using it.

Sean
	


--
 [ signature omitted ] 

Message 13 in thread

I'd say there isn't anything wrong with Trolltech's answer, although I
would claim that it is incomplete in that it doesn't give the reader the
understanding that the char * that is returned is temporary and the
developer needs to do something with it immediately if he wants to have
it around for longer than that one line of code.

Sean

-----Original Message-----
From: Sunil Thaha [mailto:sunil.thaha@xxxxxxxxx] 
Sent: Thursday, February 01, 2007 6:27 AM
To: qt-interest@xxxxxxxxxxxxx
Subject: Is there something wrong in this Qt's Faq ?

Please refer to this Faq, regarding the conversion of QString to char *
http://www.trolltech.com/developer/knowledgebase/faq.2007-01-30.90322382
53/

The Faq says to use toLatin1().data().

toLatin1() creates a temporary QByteArray which gets destroyed the next
moment ? So how correct is the answer there ?

--
 [ signature omitted ]