clue / zenity-react
Zenity allows you to build graphical desktop (GUI) applications in PHP, built on top of ReactPHP.
Fund package maintenance!
clue
clue.engineering/support
Installs: 322
Dependents: 0
Suggesters: 0
Security: 0
Stars: 126
Watchers: 12
Forks: 22
Open Issues: 13
Requires
- php: >=5.3
- react/child-process: ^0.6 || ^0.5 || ^0.4 || ^0.3
- react/event-loop: ^1.0 || ^0.5 || ^0.4 || ^0.3
- react/promise: ~2.0|~1.0
Requires (Dev)
- clue/block-react: ^1.1
- phpunit/phpunit: ^9.3 || ^5.7 || ^4.8
README
Zenity allows you to build graphical desktop (GUI) applications in PHP, built on top of ReactPHP.
Zenity is a small program that allows creating simple GTK+ dialogs from within command line scripts. Zenity already ships with Ubuntu-based distributions and does not require any installation there - so this library should work out of the box. Otherwise you may have to install Zenity yourself. This library provides an easy to use wrapper to spawn Zenity processes to build graphical desktop applications with PHP.
Table of contents
Support us
We invest a lot of time developing, maintaining and updating our awesome open-source projects. You can help us sustain this high-quality of our work by becoming a sponsor on GitHub. Sponsors get numerous benefits in return, see our sponsoring page for details.
Let's take these projects to the next level together! 🚀
Quickstart example
Once installed, you can use the following code to open a prompt asking the user for his name and presenting it in another info dialog.
<?php require __DIR__ . '/vendor/autoload.php'; $launcher = new Clue\React\Zenity\Launcher(); $entry = new EntryDialog(); $entry->setText('What\'s your name?'); $entry->setEntryText(getenv('USER')); // prefill with current user $launcher->launch($entry)->then(function ($name) use ($launcher) { $launcher->launch(new InfoDialog('Welcome to zenity-react, ' . $name .'!')); }, function (Exception $e) { echo 'Error: ' . $e->getMessage() . PHP_EOL; });
Looking for more examples? Take a look at the examples folder.
Usage
Launcher
As shown in the above example, a Launcher
has to be instantiated once and
is responsible for launching each Zenity dialog. It manages running
the underlying zenity
process and reports back its state and user interaction.
It uses the react/event-loop component to enable an async workflow where you can launch multiple dialogs while simultaneously doing more I/O work. This library exposes both a simple blocking API and a more advanced async API.
This class takes an optional LoopInterface|null $loop
parameter that can be used to
pass the event loop instance to use for this object. You can use a null
value
here in order to use the default loop.
This value SHOULD NOT be given unless you're sure you want to explicitly use a
given event loop instance.
$launcher = new Clue\React\Zenity\Launcher();
setBin()
For launching the process it assumes your zenity
binary is located in your system $PATH
.
If it's not, you can explicitly set its path like this:
$launcher->setBin('/some/other/path/zenity');
waitFor()
The waitFor($dialog)
method can be used to launch a given dialog and
wait for the Zenity process to return its result.
This simple blocking API allows you to get started quickly without exposing
all nifty async details - and lacking some of its advanced features:
$result = $launcher->waitFor($dialog);
launch()
The launch($dialog)
method can be used to asynchronously launch a given dialog
and return a Promise that will be fulfilled
when the Zenity process returns.
This async API enables you to launch multiple dialogs simultaneously while simultaneously
doing more I/O work.
$launcher->launch($dialog)->then( function ($result) { // info dialogs complete with a boolean true result // text dialogs complete with their respective text }, function ($reason) { // dialog was cancelled or there was an error launching the process } });
launchZen()
The launchZen($dialog)
method can be used to asynchronously launch a given dialog
and return an instance of the BaseZen
class.
This instance exposes methods to control the Zenity process while waiting for the results.
Some dialog types also support modifying the information presented to the user.
$zen = $launcher->launchZen($dialog); Loop::addTimer(3.0, function () use ($zen) { $zen->close(); }); $zen->promise()->then(function ($result) { // dialog completed }, function (Exception $e) { echo 'Error: ' . $e->getMessage() . PHP_EOL; });
Builder
Additionally, the Builder
implements an even simpler interface for commonly
used dialogs. This is mostly for convenience, so you can get started easier.
The methods should be fairly self-explanatory and map directly to the Zenity
dialogs listed below.
$builder = new Builder(); $dialog = $builder->info('Hello world');
For anything more complex, you can also instantiate the below classes directly.
Dialog
The Dialog
API is modelled closely after Zenity's command line API, so it should be
familiar if you're already using it from within any other command line script.
AbstractDialog
Abstract base class for all Zenity dialogs (see below for details on each concrete type).
CalendarDialog
ColorSelectionDialog
EntryDialog
$builder->entry($prompt = null, $prefill = null);
ErrorDialog
$builder->error($text, $title = null);
FileSelectionDialog
$builder->fileSelection($title = null, $multiple = false); $builder->fileSave($title = null, $previous = null); $builder->directorySelection($title = null, $multiple = false);
FormsDialog
InfoDialog
$builder->info($text, $title = null);
ListDialog
$builder->listCheck(array $list, $text = null, array $selected = null); $builder->listMenu(array $list, $text = null); $builder->listRadio(array $list, $text = null, $selected = null); $builder->table(array $rows, array $columns = null, $text = null);
Where $selected
in case of listCheck is an array of keys of the items from $list
you want to preselect.
Where $selected
in case of listRadio is the key of the item from $list
you want to preselect.
NotificationDialog
$builder->notification($text); $builder->notifier();
PasswordDialog
ProgressDialog
$builder->progress($text = null); $builder->pulsate($text = null);
QuestionDialog
$builder->question($question, $title = null);
ScaleDialog
TextInfoDialog
$builder->text($filename, $title = null); $builder->editable($filename, $title = null); $builder->confirmLicense($filename, $confirmation, $title = null);
WarningDialog
$builder->warning($text, $title = null);
Install
The recommended way to install this library is through Composer. New to Composer?
This will install the latest supported version:
composer require clue/zenity-react:^0.4.4
See also the CHANGELOG for details about version upgrades.
This project aims to run on any platform and thus does not require any PHP extensions and supports running on legacy PHP 5.3 through current PHP 8+ and HHVM. It's highly recommended to use the latest supported PHP version for this project.
Obviously, this library requires the Zenity binary itself. Zenity already ships with Ubuntu-based distributions and should not require any installation there. On Debian- and Ubuntu-based distributions you can make sure it's installed like this:
# usually not required
sudo apt-get install zenity
Otherwise you may have to install Zenity yourself (use your favorite search engine, download the appropriate release tarball or compile from source). Zenity it not officially supported on other platforms, however several non-official releases exist.
Running on Windows is currently not supported
This library assumes Zenity is installed in your PATH. If it is not, you can explicitly set its path like this:
$launcher = new Clue\React\Zenity\Launcher(); $launcher->setBin('/path/to/zenity');
Tests
To run the test suite, you first need to clone this repo and then install all dependencies through Composer:
composer install
To run the test suite, go to the project root and run:
vendor/bin/phpunit
License
This project is released under the permissive MIT license.
Did you know that I offer custom development services and issuing invoices for sponsorships of releases and for contributions? Contact me (@clue) for details.