Seite 1 von 1

OS X 10.5, Terminal Commands via QProcess, C++

Verfasst: 3. Mai 2008 19:55
von Franzac
Hi, ich bin ziemlich neu im Qt Bereich, muss aber damit anfangen aus Studiumsgründen, ist ca. 2 Monate her dass ich damit begonnen hab, läuft bisher auch eigentlich fast alles was ich so versucht hab.

Nun zu meinem Problem:
Ich möchte dass bestimmte Terminal befehle ausgeführt werden.
Beispiel hierfür:

defaults write com.apple.dock workspaces-edge-delay -float 0.5

Hiermit kann man z.B. einstellen wie lange die Verzögerung ist, wenn man ein Fenster an den Bildschirmrand hält, bis der Desktop wechselt.

Ist das überhaupt möglich?

Hier mal meine ersten Versuche, hab mich bisher eigentlich noch nicht mit QProcess auseinandergesetzt. Wär echt nett wenn mir jemand sagen was daran falsch ist, bzw. ein kurzes Codebeispiel gibt wies richtig geht.
Hier mein Versuch(in einer Funktion die mit einem Button connected ist steht das):




QProcess *Terminal = new QProcess(this);
QString program = "/Applications/Utilities/Terminal.app";

Terminal->start(program);

if(Terminal->Running)
Terminal->write("echo Test\n");

Terminal->closeWriteChannel();





Das Terminal Fenster wird zwar geöffnet, der Befehl jedoch nicht ausgeführt.
Hab im Forum schon alles Mögliche gefunden, jedoch hat mir nichts weitergeholfen, leider, ich habs zumindest nicht verstanden.

Danke schon mal für jede Antwort :)

Verfasst: 3. Mai 2008 20:05
von C167
ein Beispiel aus der Doku:

Code: Alles auswählen

QString program = "./path/to/Qt/examples/widgets/analogclock";
QStringList arguments;
arguments << "-style" << "motif";

QProcess *myProcess = new QProcess(parent);
myProcess->start(program, arguments);
Ich weiss nciht genau, wie das Programm das du startest die Befehle erwartet, wenn es aber z.B. kein interaktives ist, sollte obiges Beispiel gehen. Dabei werden alle Parameter in die QStringList geladen und dann automatisch durch Leerzeichen oder was eben notwendig ist getrennt und an den Programmaufruf angehaengt

Verfasst: 3. Mai 2008 20:15
von patrik08
Mac hat eine sehr machtige script sprache on board... mit der man alles machen kann.

"tell application Finder/Terminal " ecc

Das ist ein beispiel von desktop print screen... dort wo QT nicht hinkommt...

Aepfel + Hoch + 3

siehe auch http://qtforum.de/forum/viewtopic.php?t=2366

Code: Alles auswählen

//MacOSX
  #elif defined(Q_OS_MACX)

  //create script
  QString scriptFilename = ((Window*)qApp->mainWidget())->getTitle()->getAlbum()->getTmpDir() +
    "/tmpBackgroundScript";

  QFile file( scriptFilename );
  if(file.open(IO_WriteOnly))
  {
    //-----
    QTextStream stream;
    stream.setDevice( &file );
    stream.setEncoding( QTextStream::UnicodeUTF8 );
    //-----
    stream << "tell application \"Finder\"\n";
    stream << "set pFile to POSIX file \"" << chosenFilename.ascii() << "\"\n";
    stream << "set desktop picture to file pFile\n";
    stream << "end tell";
  }
  file.close();
 
  //run script to set background
  QProcess p;
  p.addArgument( "/usr/bin/osascript" );
  p.addArgument( scriptFilename );
  p.start();
 
  //if there is an old file remove it
  if(!oldFilename.isNull())   
  { tmpDir.remove( oldFilename ); }

  //-------------------------------
  //UNIX
  #else 


Verfasst: 3. Mai 2008 20:17
von Franzac
Anhand dieses Beispiels hatte ichs auch schon versucht, die Doku bin ich schon durchgegangen, hat leider auch nicht funktioniert. :wink:

Trotzdem Danke!

Das Terminal ist halt die "Kommandozeilenanwendung" bei OS X, das Äquivalent zu cmd.exe bei Windows (wenn man das so sagen kann).
Was du hier mit interaktiv meinst versteh ich nicht ganz.

Edit: ist an den Vorvorposter gerichtet, war zu langsam, da war auch schon wieder ein neuer Beitrag :D

@patrik08:

Ok, dann werd ich mal versuchen ob ich damit irgendwas machen kann.
Danke schon mal für deine Mühe :P

Verfasst: 3. Mai 2008 20:56
von C167
Franzac hat geschrieben:Das Terminal ist halt die "Kommandozeilenanwendung" bei OS X, das Äquivalent zu cmd.exe bei Windows (wenn man das so sagen kann).
Naja, AFAIK wie bei Linux ;) aber lass die cmd aus dem Spiel
Franzac hat geschrieben:Was du hier mit interaktiv meinst versteh ich nicht ganz.
Na, du startest und dann wartet es auf eingaben, fragt dich und so weiter.

Verfasst: 3. Mai 2008 22:45
von Franzac
Juhu, es hat funktioniert, Danke nochmal :D :

Zum einen einfach um Terminal befehle auszuführen hab ichs jetzt so gemacht:

Code: Alles auswählen

void ExecCommand (QString Command)
{	
	QProcess Process; 
	Process.startDetached(QString( Command ));
	Process.close();	
}
Funktioniert einwandfrei bis jetzt.

Und wegen dem Skript erstellen und ausführen hab ich mich auch mal an dem gepostetem Code orientiert, aber halt selbst nochmal neugeschrieben und angepasst:

Code: Alles auswählen

void CreateScript (void)
{
  QString ScriptName = "/beliebiger/Pfad/TestSkript.scpt";
  QFile File( ScriptName );
  QTextStream Stream;
  QProcess Process;
  
  File.open( QFile::WriteOnly ); 
  
  Stream.setDevice( &file ); 
  Stream.setCodec( "UTF-8" );
 
  Stream << "tell application \"Finder\"\n"; 
  Stream << "display dialog \"Test\"\n";
  Stream << "end tell"; 
  
  File.close(); 

  Process.startDetached(QString( "osascript " + ScriptName ));
}
Funktioniert ebenfalls, jedoch weiss ich hierbei nicht wie ich das Skript nach dem benutzen wieder löschen soll (mit File.remove() is klar), vielmehr wie ich abfragen kann ob das Skript schon fertig ausgeführt ist und dann löschen.
Denn wenn ich einfach in der letzten Zeile noch ein File.remove(); hinzufüge gehts leider nicht mehr..

Weiß hier vielleicht noch jemand Rat (mit dem ganzen QProcess kenn ich mich leider noch nicht aus :()

Danke schon mal.

Edit: und vielleicht hat jemand eine Empfehlung wo ich dieses Skript am besten temporär abspeichern könnte ohne dass es mir der Benutzer sieht und dann was damit anstellt, bzw. wo ich unter OS X generell Sachen die nur temporär gebraucht werden am schlauesten ablege.

Verfasst: 3. Mai 2008 23:56
von patrik08
Franzac hat geschrieben:J
Funktioniert ebenfalls, jedoch weiss ich hierbei nicht wie ich das Skript nach dem benutzen wieder löschen soll (mit File.remove() is klar), vielmehr wie ich abfragen kann ob das Skript schon fertig ausgeführt ist und dann löschen.
e.
Dafur gibt es ja signale im QProcess

http://doc.trolltech.com/4.3/qprocess.html#finished

Code: Alles auswählen

proc = new QProcess(this);  /* */
     connect(proc, SIGNAL(finished(int)),this, SLOT(RegisterPDFstream(int)));
     proc->start(Generate_Command()); 
um die .scpt file zu loeschen beispiele gibt es ja genug von beispiel script
und spezielle hilft auch http://www.osxentwicklerforum.de/board.php?boardid=74 dort sind viele mac guru


Auch interessanti ist apple event in QT:
http://doc.trolltech.com/qq/qq12-mac-events.html

Verfasst: 4. Mai 2008 10:47
von Franzac
Danke, da hätte es wohl noch ein weilchen gedauert bis ich da drauf gekommen wäre :) .

Jetzt will aber die connection bei mir nicht funktionieren.
Hier der Code und die Meldung vom Compiler:

Code: Alles auswählen

void Main::CreateScript (void) 
{ 
  QString ScriptName = "/beliebiger/Pfad/TestSkript.scpt"; 
  QFile File( ScriptName ); 
  QTextStream Stream; 
  QProcess Process; 
  
  File.open( QFile::WriteOnly ); 
  
  Stream.setDevice( &file ); 
  Stream.setCodec( "UTF-8" ); 
  
  Stream << "tell application \"Finder\"\n"; 
  Stream << "display dialog \"Test\"\n"; 
  Stream << "end tell"; 
  
  File.close(); 

 QObject::connect(Process,SIGNAL(finished(int)), this,  SLOT(DeleteSkript(ScriptName)));

  Process.startDetached(QString( "osascript " + ScriptName )); 
} 

void Main::DeleteScript(QString Path)
{
	QFile file (Path);
	file.remove();
}
Kompiler:

no matching function for call to `Main::connect(QProcess&, const char[12], Main* const, const char[26])'

Ich frag mich was ich da falsch mach?!



Danke für eure Geduld :D und Hilfe :)

Verfasst: 4. Mai 2008 10:57
von Christian81
Beschäftigt euch endlich mal mit den Qt-Grundlagen bevor mal wieder die selbe Frage auftaucht?
Signals and Slots

Verfasst: 4. Mai 2008 11:31
von Franzac
Jetzt hab ichs mir öfters durchgelesen (was ich davor auch schon gemacht hab). Hab die Variable aus den Parametern entfernt, aus meiner Funktion ebenfalls.

Funtkionieren wills trotzdem nicht, gleiche Fehlermeldung, und ich verstehs einfach nicht. Die Doku hab ich mir wirklich schon öfter durchgelesen. :(

Tut mir leid wenn ich hier so rumnerv, aber ich bin halt neu in der Materie :oops: . Ausserdem hab ich unter der Woche keinen Zugang zum Internet und dann wirds noch komplizierter für mich.

Verfasst: 5. Mai 2008 07:17
von macman
Erstell man deinen Process mit new. Ein connect erwartet auch einen Zeiger auf ein Objekt und nicht das Objekt selber.