Skip to main content

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() shows Form1 with run(Form1).
  • Console Application: Main() talks through print() / 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, MinButton and MaxButton, 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: Menu controls on the menu bar or in other menus, with Click events, Checked, Enabled, Visible and Shortcut; 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 TextFormat can be Rich Text (HTML) or Markdown, with headings, bold text and links (LinkClick event).
  • 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. A Splitter docked beside it lets the user drag its size, and ScrollBars makes 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 the Index first (def cmdDigit_Click(self, Index)). Elements are self.cmdDigit[i] or VB's self.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 its Index.
  • Return values replace ByRef arguments: return 0 from KeyPress to swallow a key (or another char code to replace it); return True from Form_Unload to 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 the vp* 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)

Source distribution for vp6 0.4.48
File Size Uploaded
vp6-0.4.48.tar.gz 1.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for vp6 0.4.48
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.4.48 This release

2 release files

0.4.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page