安装PHP7的图形用户界面(GUI) 扩展

来源:互联网 发布:手机反监控软件 编辑:程序博客网 时间:2024/05/17 23:56

今天翻了翻PHP手册,无意中发现这个PHP7才加入的新扩展:图形用户界面(GUI) 扩展 PHP-UI,觉得挺有意思的,2016年10月才发布的,网上搜了一圈发现几乎没有相关资讯,连安装说明都没有一个。。。

官方介绍原文:

This extension wraps the very excellent libui to provide PHP 7 with an API for the creation of cross platform native look-and-feel interfaces.

大概说的是:该扩展是适用于 PHP7 基于 libui 开发的跨平台图形界面接口吧。。。

PHP扩展介绍

http://php.net/ui

Github

https://github.com/krakjoe/ui

经过一番折腾,终于能运行了,
下面说说我的安装过程:(仅以Windows7为例)

1. 先下载扩展

扩展下载:https://pecl.php.net/package/ui
按照你本地的PHP7版本情况选择下载对应的扩展文件,注意:仅支持 PHP7

2. 安装扩展

解压刚才下载的压缩包
总共需要三个 .dll 文件

php_ui.dll
libui.dll
pthreadVC2.dll

安装PHP7的图形用户界面(GUI) 扩展

php_ui.dll 复制到 PHP 的 ext 目录下,
其余两个文件 libui.dllpthreadVC2.dll 放到 PHP 的根目录下,也就是与 php.exe 的同级目录

如果你之前操作不正确,在命令行中执行 PHP 时,将会弹出下面的错误提示:

无法启动此程序,因为计算机中丢失 libui.dll,尝试重新安装该程序以解决此问题。

安装PHP7的图形用户界面(GUI) 扩展

这个提示出现说明你没有放入 libui 和 pthreadVC2 文件到 php 的根目录下,重新放入就正常了。

3. 开始测试

打开之前下载的压缩包,其中有三个已写好的测试代码:
贪吃蛇游戏无限星空动画趋势图

下面运行测试代码看看效果吧:

贪吃蛇:

安装PHP7的图形用户界面(GUI) 扩展

这是个可操作的游戏哦,不过撞到自己的尾巴不会死,窗口可任意拉伸,越大行动速度就越快

无限星空图

安装PHP7的图形用户界面(GUI) 扩展

趋势图

安装PHP7的图形用户界面(GUI) 扩展

可以实时调节变化。


5.源码参考:

这是官方的测试案例源码,可以先参考下看看

贪吃蛇代码:

<?phpdefine ("PHP_UI_SECOND",    1000000);define ("PHP_UI_SNAKE_FPS", 30);use UI\Window;use UI\Point;use UI\Size;use UI\Area;use UI\Key;use UI\Controls\Box;use UI\Draw\Pen;use UI\Draw\Brush;use UI\Draw\Path;use UI\Draw\Color;use UI\Draw\Stroke;use UI\Draw\Matrix;use UI\Draw\Text\Font;use UI\Draw\Text\Font\Descriptor;use UI\Executor;$win = new class("Snake", new Size(640, 480), false) extends Window {    public function addExecutor(Executor $executor) {        $this->executors[] = $executor;    }    protected function onClosing() {        foreach ($this->executors as $executor) {            $executor->kill();        }        $this->destroy();        UI\quit();    }};$box = new Box(Box::Vertical);$win->add($box);$snake = new class($box) extends Area{    public function __construct(Box $box) {        $this->newSnake();        $box->append($this, true);    }    public function setExecutor(Executor $executor) {        $this->executor = $executor;    }    protected function onKey(string $char, int $key, int $flags) {        if ($flags & Area::Down) {            switch ($key) {                case Key::Up:                    if ($this->direction == Key::Down)                        return;                    $this->direction = $key;                break;                case Key::Down:                    if ($this->direction == Key::Up)                        return;                    $this->direction = $key;                break;                case Key::Right:                    if ($this->direction == Key::Left)                        return;                    $this->direction = $key;                break;                case Key::Left:                    if ($this->direction == Key::Right)                        return;                    $this->direction = $key;                break;                default:                    if ($char == " ") {                        $this->pause = !$this->pause;                        if ($this->pause) {                            /* this allows the CPU to idle while paused */                            $this->executor->setInterval(0);                        } else {                            /* this will (re)start the game */                            $this->executor->setInterval(PHP_UI_SECOND/PHP_UI_SNAKE_FPS);                        }                    }                break;            }        }    }    protected function onDraw(Pen $pen, Size $size, Point $clip, Size $clipSize) {        $zero = new Point(0, 0);        $frame = $zero + 40;        $frameSize = $size - 80;        $path = new Path();        $path->addRectangle($zero, $size);        $path->end();        $pen->fill($path, 0xf5f5f5ff);        $stroke = new Stroke();            $pen->stroke($path, 0x000000FF, $stroke);        $path = new Path();        $path->addRectangle($frame, $frameSize);        $path->end();        $pen->stroke($path, 0x000000FF, $stroke);        $matrix = new Matrix();        $matrix->translate($frame);        $pen->transform($matrix);        if (!$this->food) {            $this->newFood($frameSize);        }        if (!$this->pause && ($run = microtime(true)) - $this->run > 0.1 / $this->level * 2) {            $this->run = $run;            $next = clone $this->snake[0];            switch ($this->direction) {                case Key::Right: $next->x++; break;                case Key::Left:  $next->x--; break;                case Key::Up: $next->y--; break;                case Key::Down: $next->y++; break;            }            if ($next->x < 0 || $next->x >= ($frameSize->width)/10 ||                 $next->y < 0 || $next->y >= ($frameSize->height)/10) {                $this->newSnake();                $this->newFood($frameSize);                foreach ($this->snake as $body) {                    $this->newCell($pen, $body);                }                $this->newCell($pen, $this->food);                $this->pause = true;                $this->direction = Key::Right;                $this->score = 0;                $this->level = 1;                return;            }            if ($this->food == $next) {                $tail = $next;                $this->newFood($frameSize);                $this->score += 10;                $this->level = ceil($this->score / 100);            } else {                $tail = array_pop($this->snake);                $tail->x = $next->x;                $tail->y = $next->y;            }            array_unshift($this->snake, $tail);        }        foreach ($this->snake as $body) {            $this->newCell($pen, $body);        }        $this->newCell($pen, $this->food);        $matrix = new Matrix();        $matrix->translate($zero - 40);        $pen->transform($matrix);        if ($this->pause) {            $this->drawPause($pen, $size);        } else $this->drawScore($pen, $size);    }    private function newSnake() {        $this->snake = [];        for ($i = 0; $i < 5; $i++)            $this->snake[$i] = new Point($i, 0);    }    private function newFood(Size $size) {        $this->food = new Point(            floor(mt_rand(40, ($size->width ) - 10) / 10),             floor(mt_rand(40, ($size->height) - 10) / 10));    }    private function newCell(Pen $pen, Point $point) {        $path = new Path();        $path->addRectangle($point * 10, new Size(10, 10));        $path->end();        $pen->fill($path, 0x0000FFFF);        $stroke = new Stroke();        $stroke->setThickness(2);        $pen->stroke($path, 0x000000FF, $stroke);    }    private function drawPause(Pen $pen, Size $size) {        $layout = new UI\Draw\Text\Layout(sprintf(            "Press space bar to play ...",            $this->level,            $this->score        ), new Font(new Descriptor("arial", 12)), $size->width);        $layout->setColor(0x000000FF);        $pen->write(new Point(20, 10), $layout);    }    private function drawScore(Pen $pen, Size $size) {        $layout = new UI\Draw\Text\Layout(sprintf(            "Level: %d Score: %d",            $this->level,            $this->score        ), new Font(new Descriptor("arial", 12)), $size->width);        $layout->setColor(0x000000FF);        $pen->write(new Point(20, 10), $layout);    }    private $snake;    private $food;    private $direction = Key::Right;    private $level = 1;    private $score = 0;    private $pause = true;    private $run = 0;};$animator = new class ($snake) extends Executor {    public function __construct(Area $area) {        $this->area = $area;        /* construct executor with infinite timeout */        parent::__construct();    }    protected function onExecute() {        $this->area->redraw();    }};$win->addExecutor($animator);$snake->setExecutor($animator);$win->show();UI\run();

无限星空

<?phpuse UI\Window;use UI\Point;use UI\Size;use UI\Area;use UI\Key;use UI\Controls\Box;use UI\Draw\Pen;use UI\Draw\Brush;use UI\Draw\Path;use UI\Draw\Color;use UI\Executor;$win = new class("Starfield", new Size(640, 480), false) extends Window {    public function addExecutor(Executor $executor) {        $this->executors[] = $executor;    }    protected function onClosing() {        foreach ($this->executors as $executor) {            $executor->kill();        }        $this->destroy();        UI\quit();    }};$box = new Box(Box::Vertical);$win->add($box);$font = new UI\Draw\Text\Font(    new UI\Draw\Text\Font\Descriptor("arial", 12)           );$stars = new class($box, 1024, 64, $font) extends Area {    protected function onKey(string $key, int $ext, int $flags) {        if ($flags & Area::Down) {            switch ($ext) {                case Key::Up: if ($this->velocity < 40) {                    $this->velocity++;;                } break;                case Key::Down: if ($this->velocity) {                    $this->velocity--;                } break;            }        }    }    protected function onDraw(UI\Draw\Pen $pen, UI\Size $size, UI\Point $clip, UI\Size $clipSize) {        $hSize = $size / 2;        $path = new Path();        $path->addRectangle(Point::at(0), $size);        $path->end();        $pen->fill($path, 0x000000FF);        foreach ($this->stars as $idx => &$star) {            $star[1] -= $this->velocity / 10;            if ($star[1] <= 0) {                $star[0]->x = mt_rand(-25, 25);                $star[0]->y = mt_rand(-25, 25);                $star[1] = $this->depth;            }            $pos = $star[0] * (128 / $star[1]) + $hSize;            if ($pos->x >= 0 && $pos->x <= $size->width && $pos->y >= 0 && $pos->y <= $size->height) {                $starSize = (1 - $star[1] / 32) * 5;                $path = new Path();                if (PHP_OS == "WINNT") {                    $path->addRectangle($pos, new Size($starSize, $starSize));                } else {                    $path->newFigureWithArc($pos, $starSize/2, 0, M_PI*2, 0);                }                $path->end();                $color = new Color();                $color->r = $starSize;                $color->g = $starSize;                $color->b = $starSize;                if ($star[2] && $star[3]++ % 3 == 0) {                    $color->a = mt_rand(0,10) / 10;                }                $pen->fill($path, $color);            }        }        $this->writeRenderSpeed($pen, $size);    }    private function writeRenderSpeed(UI\Draw\Pen $pen, UI\Size $size) {        $now = time();        @$this->frames[$now]++;        $layout = new UI\Draw\Text\Layout(sprintf(            "%d fps",            isset($this->frames[$now - 1]) ?                 $this->frames[$now-1] : $this->frames[$now]        ), $this->font, $size->width);        $layout->setColor(0xFFFFFFFF);        $pen->write(new Point(20, 20), $layout);        unset($this->frames[$now-2]);    }    public function __construct($box, $max, $depth, $font, $velocity = 2) {        $this->box = $box;        $this->max = $max;        $this->depth = $depth;        $this->font = $font;        $this->velocity = $velocity;        for ($i = 0; $i < $this->max; $i++) {            $this->stars[] = [                new Point(mt_rand(-25, 25), mt_rand(-25, 25)),                mt_rand(1, $this->depth),                mt_rand(0, 1),                0            ];        }        $this->box->append($this, true);    }};$animator = new class(1000000/60, $stars) extends Executor {    protected function onExecute() {        $this->area->redraw();    }    public function __construct(int $microseconds, Area $area) {        $this->area = $area;        parent::__construct($microseconds);    }};$win->addExecutor($animator);$win->show();UI\run();

趋势图:

<?phpuse UI\Point;use UI\Size;use UI\Window;use UI\Controls\Box;use UI\Controls\Spin;use UI\Controls\ColorButton;use UI\Controls\Button;use UI\Controls\Entry;use UI\Controls\Label;use UI\Controls\Combo;use UI\Area;use UI\Draw\Pen;use UI\Draw\Path;use UI\Draw\Color;use UI\Draw\Brush;use UI\Draw\Stroke;use UI\Draw\Matrix;use UI\Draw\Text\Font\Descriptor;use UI\Draw\Text\Font;use UI\Draw\Text\Layout;$window = new Window("libui Histogram Example", new Size(640, 480), true);$window->setMargin(true);$hBox = new Box(Box::Horizontal);$hBox->setPadded(true);$vBox = new Box(Box::Vertical);$vBox->setPadded(true);$window->add($hBox);$hBox->append($vBox);$dataSources = [];$histogram = new class($dataSources) extends Area {    private function getGraphPoints(Size $size) : array {        $xincr = $size->width / 9;        $yincr = $size->height / 100;        $points = [];        foreach ($this->sources as $i => $source) {            $points[$i] = new Point($xincr * $i, $yincr * (100 - $source->getValue()));        }        return $points;    }    private function getGraphPath(array $locations, Size $size, bool $extend = false) : Path {        $path = new Path();        $path->newFigure(array_shift($locations));        foreach ($locations as $location) {            $path->lineTo($location);        }        if ($extend) {            $path->lineTo(Point::at($size));            $path->lineTo(new Point(0, $size->height));            $path->closeFigure();        }        $path->end();        return $path;    }    protected function onDraw(Pen $pen, Size $areaSize, Point $clipPoint, Size $clipSize) {        $start = microtime(true);        $path = new Path();        $path->addRectangle($clipPoint, $areaSize);        $path->end();        $pen->fill($path, 0xFFFFFFFF);        $graphSize = $areaSize - 40;        $zero = Point::at(20);        $path = new Path();        $path->newFigure($zero);        $path->lineTo(new Point(20, 20 + $graphSize->height));        $path->lineTo(Point::at($graphSize + 20));            $path->end();        $stroke = new Stroke();        $stroke->setThickness(2);        $pen->stroke($path, 0x000000FF, $stroke);        $matrix = new Matrix();        $matrix->translate($zero);        $pen->transform($matrix);        $points = $this->getGraphPoints($graphSize);        $path = $this->getGraphPath($points, $graphSize, true);        $brush = new Brush($this->color->getColor());        $pen->fill($path, $brush);        $path = $this->getGraphPath($points, $graphSize, false);        $strokeColor = $brush->getColor();        $strokeColor->a /= 2;        $brush->setColor($strokeColor);        $pen->stroke($path, $brush, $stroke);        $layout = new Layout(sprintf(            "Drawn in %.5f seconds",                 microtime(true) - $start),            $this->font->getFont(),            $clipSize->width        );        $layout->setColor(0x000000FF);        $pen->write(new Point(10, $graphSize->height - 30), $layout);    }    public function setColorSource(ColorButton $source) {        $this->color = $source;    }    public function getColorSource() {        return $this->color;    }    public function setFontSource(Combo $font) {        $this->font = $font;    }    public function getFontSource() {        return $this->font;    }    public function __construct(array &$sources, ColorButton $color = null, Font $font = null) {        $this->sources =& $sources;        $this->color  = $color;        $this->font = $font;    }    private $sources;    private $color;    private $font;};$colorBox = new Entry();$colorBox->setText("0x8892BFFF");$colorButton = new class($histogram, $colorBox, new Color(0x8892BFFF)) extends ColorButton {    protected function onChange() {        $redrawColor = $this->getColor();        $this->entry->setText(sprintf(            "0x%02X%02X%02X%02X",                $redrawColor->r * 255,                $redrawColor->g * 255,                $redrawColor->b * 255,                $redrawColor->a * 255));        $this->histogram->redraw();    }    public function __construct(Area $histogram, Entry $entry, Color $color) {        $this->histogram = $histogram;        $this->entry = $entry;        $this->setColor($color);        $this->histogram->setColorSource($this);    }    private $histogram;};$redrawHistogram = function() use($histogram, $colorBox, $colorButton) {    $redrawColor = $colorButton->getColor();    $colorBox->setText(sprintf(        "0x%02X%02X%02X%02X",            $redrawColor->r * 255,            $redrawColor->g * 255,            $redrawColor->b * 255,            $redrawColor->a * 255));    $histogram->redraw();};$vBox->append(new Label("Change Data:"));for ($i = 0; $i < 10; $i++) {    $dataSources[$i] = new class(0, 100, $redrawHistogram) extends Spin {        protected function onChange() {            ($this->redraw)();        }        public function __construct($min, $max, Closure $redraw) {            parent::__construct($min, $max);            $this->redraw = $redraw;        }        private $redraw;    };    $dataSources[$i]->setValue(mt_rand(0, 100));    $vBox->append($dataSources[$i]);}$vBox->append(new Label("Choose Color:"));$vBox->append($colorButton);$colorBoxButton = new class("Set Color", $colorButton, $colorBox, $redrawHistogram) extends Button {    protected function onClick() {        $this->button->setColor(            new Color(                hexdec($this->entry->getText())));        ($this->redraw)();    }    public function __construct(string $text, ColorButton $button, Entry $entry, Closure $redraw) {        $this->button = $button;        $this->entry = $entry;        $this->redraw = $redraw;        parent::__construct($text);    }    private $button;    private $entry;    private $redraw;};$vBox->append($colorBox);$vBox->append($colorBoxButton);$vBox->append(new Label("Choose Font:"));$fontCombo = new class($histogram) extends Combo {    public function onSelected() {        $this->histogram->redraw();    }    public function __construct(Area $histogram) {        $this->families  = UI\Draw\Text\Font\fontFamilies();        $this->histogram = $histogram;        sort($this->families);        foreach ($this->families as $family) {            $this->append($family);        }        $this->setSelected(0);        $this->histogram->setFontSource($this);    }    public function getFont(int $selected = -1, int $size = 12) {        return new Font(            new Descriptor($this->families[                $selected > -1 ? $families : $this->getSelected()            ], $size));    }    private $items;    private $families;};$vBox->append($fontCombo);$hBox->append($histogram, true);$window->show();UI\run();?>
0 0
原创粉丝点击