The QFile class is severely broken. If you create a new QFile() with a name it "claims" to automatically open the file for you, but it never does. Even if you Close() the file and re-open it you will get an error saying file is already open. Probably the most frustrating is the following error message: QIODevice::open: File access not specified caused by this statement: outF.Open( Qyoto.Qyoto.GetCPPEnumValue("Qt.QIODevice", "WriteOnly")); the following: <code> //QFileInfo fi = new QFileInfo( QDir.Temp(), "bynumbers.txt"); //Console.WriteLine( fi.AbsoluteFilePath()); QFile outF = new QFile( "/tmp/bynumbers.txt" ); // Console.WriteLine("about to close"); // outF.Close(); // major bug where QFile tries to open //Console.WriteLine( "about to set text"); //outF.SetTextModeEnabled( true); HandleQtEvents(); // Console.WriteLine( "about to open"); outF.Open( Qyoto.Qyoto.GetCPPEnumValue("Qt.QIODevice", "WriteOnly")); //Console.WriteLine( "file opened"); HandleQtEvents(); QTextStream outFile = new QTextStream( outF); HandleQtEvents(); DateTime today = DateTime.Now; int padCount1 = 34 - today.ToString().Length; int padCount2 = 39 - ("Drawing Data".Length/2) - 9; string outStr = string.Format( "{0}{1}Drawing Data{2}Page {3,4:0000}\n\n", today.ToString(), " ".PadLeft( padCount1), " ".PadLeft( padCount2), 1); Console.WriteLine( outStr); outFile.Write( outStr); string drawDtStr; while( q.Next()) { HandleQtEvents(); QSqlRecord rec = q.Record(); drawDtStr = rec.Field("DRAW_DT").Value().ToDate().ToString("yyyy/MM/dd"); no1 = rec.Field("NO_1").Value().ToInt(); no2 = rec.Field("NO_2").Value().ToInt(); no3 = rec.Field("NO_3").Value().ToInt(); no4 = rec.Field("NO_4").Value().ToInt(); no5 = rec.Field("NO_5").Value().ToInt(); megaNo = rec.Field("MEGA_NO").Value().ToInt(); HandleQtEvents(); outStr = string.Format( "{0,10} {1,5:00} {2,5:00} {3,5:00} {4,5:00} {5,5:00} {6,5:00}\n", drawDtStr, no1, no2, no3, no4, no5, megaNo); outFile.Write(outStr); Console.WriteLine( outStr); } // end while loop outFile.Flush(); q.Finish(); //outF.Close(); </code> creates the following CONSOLE output: cmdStr:select * from drawing_data where (no_1 = 8 or no_2 = 8 or no_3 = 8 or no_4 = 8 or no_5 = 8 or mega_no = 8) and (no_1 = 39 or no_2 = 39 or no_3 = 39 or no_4 = 39 or no_5 = 39 or mega_no = 39) ; QIODevice::open: File access not specified 8/11/2011 6:55:10 PM Drawing Data Page 0001 2010/01/26 07 08 38 39 48 22 2008/06/27 08 14 22 39 50 44 2008/01/29 08 23 39 40 42 24 2006/05/05 08 20 39 53 55 10 but the file is never created. This is really bad. QFile() shouldn't be "helping you out" by automatically attempting a file open. Worse yet, it should actually succeed don't you thing? I searched high and low for the syntax that would cause a 2 to pop out for the WriteOnly attribute. I'm quite ticked that it gets ignored.
It works exactly as it's supposed to. First, the QFile constructor does NOT open the file for you. (I wonder where you got that from, certainly it doesn't say so in the Qt docs). Second, you're doing it wrong. See the following snippet to learn how to do it the right way: using System; using Qyoto; class MainClass { public static void Main(string[] args) { new QCoreApplication(args); // just for Qyoto initialization QFile file = new QFile("hello.txt"); file.Open((uint) QIODevice.OpenModeFlag.WriteOnly); QTextStream stream = new QTextStream(file); stream.Write("Hello World!"); file.Close(); } }
That's what I love! Speak with great authority directly out rectal sphincter on a Friday without testing the actual case presented. Add one line to your "proof" and QFile is horribly busted. using System; using Qyoto; class MainClass { public static void Main(string[] args) { new QCoreApplication(args); // just for Qyoto initialization QFile file = new QFile("hello.txt"); file.SetTextModeEnabled( true); // notice this one line file.Open((uint) QIODevice.OpenModeFlag.WriteOnly); QTextStream stream = new QTextStream(file); stream.Write("Hello World!"); file.Close(); } } mcs test_snippet_1.cs -r:/usr/lib/mono/qyoto/qt-dotnet.dll roland@linux-c345:~/mega_mono_qt> mono test_snippet_1.exe QFile::open: File (hello.txt) already open QIODevice::write: ReadOnly device roland@linux-c345:~/mega_mono_qt> dir *.txt ls: cannot access *.txt: No such file or directory roland@linux-c345:~/mega_mono_qt> As to my using: Qyoto.Qyoto.GetCPPEnumValue("Qt.QIODevice","WriteOnly")); I did that because that is what the UI compiler generates in its code and that is what you find in examples. I agree your method is cleaner, but I could not find it documented, hence, one of the main reasons I'm writing this book.
I hate it when I forget to log in first! That's what I love! Speak with great authority directly out rectal sphincter on a Friday without testing the actual case presented. It's always entertaining! Add one line to your "proof" and QFile is horribly busted. using System; using Qyoto; class MainClass { public static void Main(string[] args) { new QCoreApplication(args); // just for Qyoto initialization QFile file = new QFile("hello.txt"); file.SetTextModeEnabled( true); // ****notice this one line file.Open((uint) QIODevice.OpenModeFlag.WriteOnly); QTextStream stream = new QTextStream(file); stream.Write("Hello World!"); file.Close(); } } mcs test_snippet_1.cs -r:/usr/lib/mono/qyoto/qt-dotnet.dll roland@linux-c345:~/mega_mono_qt> mono test_snippet_1.exe QFile::open: File (hello.txt) already open QIODevice::write: ReadOnly device roland@linux-c345:~/mega_mono_qt> dir *.txt ls: cannot access *.txt: No such file or directory roland@linux-c345:~/mega_mono_qt> As to my using: Qyoto.Qyoto.GetCPPEnumValue("Qt.QIODevice","WriteOnly")); I did that because that is what the UI compiler generates in its code and that is what you find in examples. I agree your method is cleaner, but I could not find it documented, hence, one of the main reasons I'm writing this book.
Yep, you're right. Setting this flag at that point will make it work incorrectly. However, this has nothing to do with the bindings. It's the same behaviour if you write it in plain C++/Qt (example attached). Solution: Call SetTextModeEnabled(true) *after* you've opened the file. Then it should work as expected. Regarding me not testing the actual case presented: I didn't do that because your example isn't self-contained. This has nothing to do with me being rude or anything. It's just that I can't compile and test your example code without modifying it (and thus maybe erasing the bug), which makes it *very* difficult to track down the actual bug. Sorry if I seemed rude or arrogant, that certainly hasn't been my intention.
Created attachment 62786 [details] C++ example with error
Send this bug up-stream then. A "set" method should only "set" a property, never actually OPEN a file. I will agree this is a baseline Qt bug, but the bug needs to be bubbled up from here since it was found here and we have complete examples that reproduce it consistently. Please "bubble-up" to Nokia.
http://www.qtcentre.org/threads/20543-QFile-and-setTextMode so the issue seems to be known. Personally, I don't think this that this is actually a bug. The method only sets the QIODevice::Text flag for the open mode, which doesn't make sense if the file is not yet opened. Closing this bug now. If you still think it's a bug, please go ahead and report it on the Qt bugtracker.