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

Alles rund um die Programmierung mit Qt
Antworten
Franzac
Beiträge: 5
Registriert: 3. Mai 2008 10:46

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

Beitrag 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 :)
C167
Beiträge: 105
Registriert: 9. Februar 2008 20:30

Beitrag 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
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag 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 

.........................
speack português italiano deutsch english castellà qt
Franzac
Beiträge: 5
Registriert: 3. Mai 2008 10:46

Beitrag 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
C167
Beiträge: 105
Registriert: 9. Februar 2008 20:30

Beitrag 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.
Franzac
Beiträge: 5
Registriert: 3. Mai 2008 10:46

Beitrag 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.
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag 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
.........................
speack português italiano deutsch english castellà qt
Franzac
Beiträge: 5
Registriert: 3. Mai 2008 10:46

Beitrag 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 :)
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Beschäftigt euch endlich mal mit den Qt-Grundlagen bevor mal wieder die selbe Frage auftaucht?
Signals and Slots
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Franzac
Beiträge: 5
Registriert: 3. Mai 2008 10:46

Beitrag 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.
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Erstell man deinen Process mit new. Ein connect erwartet auch einen Zeiger auf ein Objekt und nicht das Objekt selber.
Die deutsche Schriftsprache ist case-sensitive. Außerdem gibt es eine Interpunktionsnorm. Wenn manch einer seine Programme genauso schlampig schreibt, wie sein Posting hier, dann sollte er es lieber bleiben lassen.
Antworten