VP6
VB6-style programming for Python: an IDE where you draw forms,
set properties, double-click a control to write its event handler and press
F5 to run, plus the vp6 framework that makes the resulting code work
(also usable without the IDE).
Built on PySide6 (Qt).
Detailed documentation is in docs/: architecture, source reference, API reference and development guide.
Getting started
From PyPI:
pip install vp6 # then: vp6 (the IDE), vp6-run Project.vp6p
pip install "vp6[make]" # also vp6-make --exe: standalone executables
From the source:
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/vp6 # start the IDE (or: python -m vp6.ide)
.venv/bin/vp6 path/to/Project.vp6p # open a project
.venv/bin/vp6 --no-splash # without the two-second splash screen
.venv/bin/vp6 --help # the command line options (vp6-run and vp6-make too)
To package a program as a wheel for pip (Project > Build Wheel, or vp6-make Project.vp6p), nothing more is needed; see Building a wheel.
To make standalone executables (File > Make Executable…, or vp6-make --exe Project.vp6p), install PyInstaller too: .venv/bin/pip install -e ".[dev,make]".
Executables are made for the system they are made on (macOS, Windows,
Linux); see Making an executable.
The IDE opens with a VB-style New Project dialog. Every new project has
Form1 and Module1 and starts in Sub Main, the Main() function in
Module1:
- Standard EXE:
Main()showsForm1withrun(Form1). - Console Application:
Main()talks throughprint()/input(). - Kitchen Sink: a demo project showing every VP6 control and feature, explorer-style: choose a topic in the tree on the left and its page, a form of its own, is shown beside it. Open the pages to see how things work, and copy code out of them.
The IDE
| VB6 | VP6 |
|---|---|
| Toolbox | Pointer, PictureBox, Label, TextBox, Frame, CommandButton, CheckBox, OptionButton, ComboBox, ListBox, HScrollBar, VScrollBar, Timer, DriveListBox, DirListBox, FileListBox, Shape, Line, Image, TreeView, Splitter, ProgressBar, Slider, UpDown, StatusBar, TabStrip, ImageList, CommonDialog, Toolbar, ListView, RichTextBox, CodeBox, FlexGrid, WebView, WebBrowser, Process, Terminal, DockPanel |
| Form designer | Draw controls, move/resize with 8px grid snapping (hold Alt to skip it), rubber-band select, Ctrl+drag inside a Frame, arrows nudge, Shift+arrows resize, cut/copy/paste, undo/redo; TabIndex values are renumbered automatically when controls are added, deleted or given a new TabIndex |
| Properties window (F4) | Object combo (control array elements as cmdDigit(0)), VB's Alphabetic and Categorized tabs ((Name) and Index first, then an alphabetical grid; or under Appearance, Behavior, Font, List, Misc, Position and Text headings that collapse and expand), enum/color/list/font/file editors, multi-select editing, description pane; select a form in the Project Explorer to edit its properties and controls without opening it, or the project to edit its Name, Type, StartupObject, ColorScheme and Icon |
| Object Browser (F2) | View > Object Browser, as VB's: VP6's classes (controls, Form, Picture...), objects (App, Screen, Printer...), functions and constants, and the project's forms, user controls and modules with their controls, methods, properties, events and variables; a library list, search, each member's declaration and description; double-click a project member to go to its code (or a control to its form) |
| Code window (F7) | Object and Procedure dropdowns that create handler stubs, Python highlighting, auto-indent, self. / self.Control. completion, Ctrl+/ comments; Edit > Find (Ctrl+F; the first match is highlighted as you type), Find Next/Previous (F3 / Shift+F3), Replace (Ctrl+H, or ⌥⌘F on macOS), with match case, whole word and Python regular expressions (escapes such as \n, groups such as \1 in find and replace), in the current module or the whole project (VB's Search: Find Next goes from file to file, Replace All replaces in every file, Find All lists the matches); Edit > Go to Line (Ctrl+L) |
| Project Explorer (Ctrl+R) | Forms and modules organized in groups and subgroups (Forms and Modules to begin with; New Group, Rename, Delete, Move to, or drag and drop, several items at once; not folders on disk; +/- expands or collapses them all; Rename File… and Delete File… for a form's or module's file, its imports following a new name), or a Files view of the project's folder as it is on disk (hidden files on request; new folders and subfolders with its New Folder button or Project > Add Folder…, rename, delete, and move files and folders by drag and drop), sorted by name (the Name button cycles through A to Z with the groups first, A to Z with the groups among the files, and the same Z to A; remembered), a group's name editable in the Properties window, View Code / View Object, set startup form; follows the active window |
| Save Project As | File > Save Project As… copies the project, unsaved changes included, to a new folder named after the new project file (or into an empty folder chosen), not its dist, build or hidden files; then the IDE works on the copy and the original stays as last saved |
| Immediate window (Ctrl+G) | Program output and Debug.Print, stdin for console apps, double-click a traceback line to jump to it |
| Outline window | The structure of the current file: constants, variables, classes and their members, functions, top-level code, with type icons; sort by file order, name or type; click an item to go to its line; the item the cursor is in is highlighted. It takes the Properties panel's place while a code window is active, and gives it back for designers (also View > Outline Window and F4) |
| Output window | The IDE's own output, including library messages such as Qt warnings (hidden by default; View > Output Window) |
| Menu Editor (Ctrl+E) | Tools > Menu Editor designs the form's menus like VB's: Caption (- for a separator), Name, Index, Shortcut, Checked, Enabled, Visible, with arrows to indent and move items. The designer shows the menu bar; click a menu to see it and an item to open its Click code |
| MDI forms | Project > Add MDI Form: an MDIForm, a window for the forms whose MDIChild is True (its workspace around docked controls, Arrange, ActiveForm, the active child's menus, a WindowList menu); ShowPopup shows a form as a popup that doesn't take the focus |
| Format menu | Align, Make Same Size, Center in Form, Bring to Front (Ctrl+J), Send to Back (Ctrl+K), Lock Controls (the form's controls can't be moved or resized with the mouse or the arrow keys; hollow handles; remembered per form) |
| Run (F5 or Cmd+Enter / Ctrl+Enter, Shift+F5, End) | Saves everything and runs the project in a separate process; the title shows [design] / [run] |
| Toolbar and layout | Sun/moon switch at the right end of the toolbar toggles light/dark; View > Toolbars shows a hidden toolbar; View > Reset Window Layout restores all panels; panels at the bottom edge are always tabs; a form's window opens just large enough to show the whole form (or filling the main area when it can't), and every window opens inside the main area |
Themes: light and dark
The IDE uses System by default: the whole IDE (windows, menus, docks, icons) and the code editor follow the OS appearance live. Use View > Editor Theme to pick a theme directly. Choosing Light, Dark or a custom theme switches the entire IDE to that theme's light or dark appearance, whatever the OS setting. On platforms that can't switch an app's appearance, VP6 uses Qt's Fusion style with a light or dark palette. In the designer, a form set to System still shows the OS appearance, since that's how it will run. In Tools > Options you can:
- choose which theme is used for light and for dark system appearance,
- change any color (background, text, selection, current line, line numbers, designer region, Immediate output) and each syntax element's color, bold and italic, with a live preview,
- create your own themes (New…), delete them, or Reset a built-in theme to its defaults,
- choose the code font and size,
- choose the window frame the form designer draws around forms. Automatic
matches your OS; the others are macOS, Windows 11, GNOME or classic VB6,
handy when you design on one OS for another. The frame follows the form's
BorderStyle,ControlBox,MinButtonandMaxButton, like the real window. You can also hide the grid (controls still snap to it).
Light and dark forms
Each project has a Color Scheme (Project > Project Properties):
System (the default), Light, Dark or Follow the IDE. Every form inherits it unless its
own ColorScheme property overrides it:
ColorScheme |
Result |
|---|---|
0 - Project Default (default) |
The project's color scheme |
1 - System |
Native look, follows the OS light/dark appearance live |
2 - Light / 3 - Dark |
Always light / always dark, whatever the OS setting |
4 - IDE |
Follows the VP6 IDE's light/dark setting (e.g. the toolbar switch): live in the designer; when run from the IDE, the IDE's setting at launch; when run on its own, System |
Forced light and dark use Qt's Fusion style with a fixed palette, because
native styles such as macOS ignore per-window palettes. MsgBox and
InputBox take the scheme of the form they appear over. BackColor and
ForeColor still override the scheme's colors.
The form designer shows the form (controls and title bar) in the form's own
scheme, exactly as it will run. The workspace around the form follows the
IDE's light/dark mode. When a form runs on its own (python Form1.py),
"Project Default" is read from a .vp6p file in the same folder, if there
is one.
Files
A project is a folder with a Name.vp6p project file listing forms, modules,
user controls (controls of your own, designed like forms and placed on forms
from the Toolbox, as VB's UserControl) and the startup object (a form or
Sub Main), and how the Project panel groups them. Groups are only for the panel: files stay where they are on
disk. A group can hold forms, modules and other groups. Forms and modules
can also be in subfolders of the project's folder (organize them in the
Project panel's Files view); they import each other by file name wherever
they are, so their file names are unique in a project. The program's icon
(its windows, and the Dock or taskbar) is the project's icon: new projects
have none and show the VP6 icon from the VP6 installation until you set your
own (the project's Icon in the Properties window). The project file is
also an executable launcher script, so it starts the program by itself:
./Calculator.vp6p # uses the first python3 on PATH
VP6_PYTHON=/path/to/venv/bin/python ./Calculator.vp6p
python3 Calculator.vp6p # also works (e.g. on Windows)
It begins with #!/bin/sh and the line
"exec" "${VP6_PYTHON:-python3}" "$0" "$@". The shell runs that line to
re-execute the file with Python, and to Python it is just a string. If that
Python doesn't have VP6 installed, the script says so and how to fix it.
The project data is a PROJECT = {...} dict in a region the IDE maintains
and reads with ast, so opening a project never runs it. Code you add
outside the region is kept when the IDE saves, and saving keeps the file
executable. F5 in the IDE runs this same script.
A form is one Python file. The designer owns a clearly marked region inside the class; everything else is yours:
from vp6 import *
class Form1(Form):
# region VP6 Designer - generated by the form designer, do not edit
def InitializeComponent(self):
self.Caption = 'Hello'
self.Width = 480
self.Height = 360
self.Command1 = CommandButton(self, Caption='&Say Hello', Left=16, Top=16,
Width=104, Height=32)
# endregion
def Command1_Click(self):
MsgBox("Hello, world!", vpInformation)
if __name__ == "__main__":
run(Form1)
The IDE parses the region with ast (your code is never executed while
designing) and rewrites only that region. In the code window it is folded
and read-only. Forms run on their own too: python Form1.py.
The framework
from vp6 import *
- Events are methods named
Object_Event:Command1_Click,Text1_Change,Form_Load,List1_DblClick,Timer1_Timer,Picture1_MouseDown(self, Button, Shift, X, Y),Text1_KeyPress(self, KeyAscii), ... Handlers may declare fewer parameters than VB passes. - Menus:
Menucontrols on the menu bar or in other menus, withClickevents,Checked,Enabled,VisibleandShortcut; menus can be control arrays (e.g. a recent files list). On macOS they are in the macOS menu bar. - Formatted labels: a Label's
TextFormatcan be Rich Text (HTML) or Markdown, with headings, bold text and links (LinkClickevent). - Docked panes: a PictureBox with
Align(Top, Bottom, Left, Right) sticks to that edge of the form and follows its size, e.g. a sidebar or a status bar. ASplitterdocked beside it lets the user drag its size, andScrollBarsmakes a PictureBox scroll the controls (or form) in it. - Forms inside forms:
frmPage().ShowIn(self.picContent)shows a form designed on its own inside a PictureBox or Frame of another form, filling it and following its size;ShowIn(None)makes it a window again. - Control arrays: controls sharing a name, told apart by
Index, with one handler that gets theIndexfirst (def cmdDigit_Click(self, Index)). Elements areself.cmdDigit[i]or VB'sself.cmdDigit(i);Load(self.cmdDigit, i)/Unload(self.cmdDigit, i)add and remove elements at run time. In the designer, paste a copy of a control (VB asks whether to create a control array), give a control another control's name, or set itsIndex. - Return values replace ByRef arguments: return
0fromKeyPressto swallow a key (or another char code to replace it); returnTruefromForm_Unloadto cancel closing. - Properties have VB names and pixel units:
Caption,Text,Left,Top,Width,Height,Enabled,Visible,BackColor,ForeColor,FontName,FontSize,FontBold,TabIndex,ToolTipText,Tag,Value,List,ListIndex,ListCount,Interval, ... A misspelled property raises instead of silently creating an attribute. - Form:
Show(vpModal),Hide(),Unload(),Controls,Me,KeyPreview,BorderStyle,StartUpPosition,WindowState; a Default button reacts to Enter and a Cancel button to Esc. - Globals:
MsgBox,InputBox,RGB,QBColor,DoEvents,End,Beep,Load,Unload,Forms,App,Screen,Clipboard,Debug.Print, and thevp*constants (vpYesNo,vpYes,vpKeyReturn,vpRed,vpChecked,vpModal, ...). - Colors are VB-style BGR integers (
RGB(255, 0, 0) == vpRed == 0x0000FF). Color properties also accept"#RRGGBB". - Unhandled exceptions in event handlers show a VB-style Run-time error box with End / Continue, and the traceback goes to the Immediate window.
Tests
.venv/bin/python -m pytest
The tests run headless (QT_QPA_PLATFORM=offscreen). They cover the
runtime, the form file format, designer operations and the IDE, including
running a console project through the Immediate window.
Features and backlog
FEATURES.md lists everything VP6 implements. BACKLOG.md lists what isn't implemented yet. The biggest gaps are:
- debugging (breakpoints, stepping, evaluating code in the Immediate window);
- graphics methods (
Line,Circle,PSet); - more controls (Shape, DriveListBox, common controls);
- MDI forms;
- packaging an app as an executable.
Metadata
Release files for vp6 0.4.48
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vp6-0.4.48.tar.gz | 1.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vp6-0.4.48-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.0 MB
Release files / vp6-0.4.48.tar.gz
| Download URL | vp6-0.4.48.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5f72195dc47dea7906a8966b31381f6051f213bd0756d922e6de26ae2e30ab20
|
|
BLAKE2b-256 checksum How to use checksums |
cc44c900fccfe3f6d308f79b5865025194dee5eb3a7a87eff2ba0a8ce40fd1c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.
Transparency logRelease files / vp6-0.4.48-py3-none-any.whl
| Download URL | vp6-0.4.48-py3-none-any.whl |
|---|---|
| Size | 832.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ebe9b0094e3740e7750fe38d35aa0892beeed1ea05a7d5d400d5b4c743710735
|
|
BLAKE2b-256 checksum How to use checksums |
e36db7256e65bb3fe5dad7e91ba59c98c0c136d19d0d9a84f75fc437a5c2725d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.
Transparency log