Open-source project
cdhigh/Vb6Tkinter avatar
cdhigh/Vb6Tkinter

Vb6Tkinter: design a Tkinter GUI by dragging controls in Visual Basic 6

An add-in for VB6 designed for Tkinter (直接使用VB6设计Tkinter GUI界面)

575 stars139 forksVisual Basic 6.0MIT

At a glance

What is it?
Vb6Tkinter is a Visual Basic 6 add-in that lets you lay out a Python Tkinter interface with the VB6 form designer, maps most VB6 control properties onto their Tkinter equivalents, and generates the Python code including the callback scaffolding. It is MIT licensed, and the author recommends it for small applications rather than complex ones.
Who is it for?
Vb6Tkinter fits a developer who knows Tkinter but does not want to hand write layout code, and who is comfortable with Visual Basic 6 as a design tool but writes the application in Python. It does not fit a team with a large or complex interface, because the author says so himself, and it does not fit a team without a VB6 licence, since the add-in runs inside the VB6 IDE and registers itself as a COM add-in.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 28 days ago.
What is it written in?
Mainly Visual Basic 6.0, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the add-in actually does

Vb6Tkinter is a Visual Basic 6 add-in, an external program, whose purpose is to let you design a Python Tkinter GUI interface directly inside the VB6 development environment. You drag and drop controls on a form, set most of their properties in the VB6 property grid, and the add-in generates the necessary Python code, including the callback function framework. Once the code is generated you add the actual logic in the corresponding callbacks.

The project description states the scope plainly: it supports the large majority of Tkinter controls and is enough for ordinary GUI needs, with the control list given in the documentation. The English documentation itself is in a separate Readme_EN.md file.

The idea is a visual design tool that is not Python. The form designer in VB6 is a mature drag and drop layout environment with a property grid, and the add-in translates that into Tkinter widget calls. You end up with a Python file, not a VB6 program.

The audience is specific and the documentation is explicit about who it is for: developers who have learned Tkinter and do not want the trouble of hand writing GUI generation and layout code, and who also do not want to use third party tools and frameworks such as wxPython or PyQt. It is also aimed at small programs with a not too complex interface, and the author says plainly that for a complex interface you should use wxPython or PyQt instead.

The other argument in the documentation is about what ships to the user. Since Tkinter is part of the Python standard library, a program written with it can be called green software, meaning it does not need wxPython or PyQt installed on the target machine, only Python. Even packaged with pyinstaller or cx_freeze into an exe, the final file is not large. And for a program whose logic is not complicated, one .py file is usually enough, unlike some auxiliary frameworks that need several.

The two installation routes and the VB6 dependency

The documentation offers two ways to install, and the choice is mostly about whether you want the add-in bundled with an IDE or added to an existing one.

The integrated route downloads a package from the releases page that bundles a slimmed down VB6 with the various patches already applied, and you double click the installer. Nothing else is needed.

The standalone route is more manual. You download the plugin archive from the same releases page and extract it to a directory. You then install VB6 yourself, either the full version or a slimmed one. On Windows 7 and later you overwrite the original Vb6.exe with the Vb6.exe from Vb6_SP6_Fix_for_Win7.zip, and on Windows 10 and later you apply the VB6_AppCompat patch. Then you register the plugin, either with the bundled registration tool Setup for Vb6Tkinter.exe or by hand, by running `regsvr32 /s diretory\Vb6Tkinter.dll` and adding a line to the Add-Ins32 section of C:\Windows\VBADDIN.INI: `Vb6Tkinter.Connect=3`.

Upgrading afterwards is only a file copy, downloading the new Vb6Tkinter.dll and Vb6Tkinter.lng and replacing the old ones.

The dependency on VB6 is the real cost here, and it is worth being blunt about. The add-in is a COM component registered into the VB6 IDE, and the tool it plugs into is a Microsoft product from 1998 that needs patching to run on a current Windows. A team that has moved on from VB6 has to justify keeping a VB6 toolchain, patched or not, in its build and provisioning process, purely to lay out a Tkinter interface.

The design and code generation workflow, step by step

The usage walkthrough in the documentation is short enough to follow in full.

You open VB6, create a standard EXE project, and design your GUI layout on the form, which the author says should be doable even without VB experience, and you can set the control properties there. If you do not want the form to be resizable, the advice is to set the form's BorderStyle property to Fixed Single or Fixed Dialog in VB6.

If you used the bundled installer, a new icon appears on the VB toolbar, described as an orange-red feather. If not, you start Vb6Tkinter from the Add-Ins menu and the Add-In Manager, and the icon and menu appear.

Then the workflow proper. You press the refresh form list button to list all forms and controls in the current project. You go through the controls one by one, tick the output properties you want, and if needed double click a property in the list to change its value. The documentation notes that in general you do not need to change control properties again, because Vb6Tkinter translates VB control properties into Tkinter control properties as far as it can, covering font, colours, initial values, appearance and state, and even shortcut settings for button-like controls and menus.

You press the generate code button and the code appears in a preview window, which you can double click to enlarge or edit directly. When you are happy you copy it to the clipboard or save it to a file.

Two structural choices come at the end of the workflow. Layout can be percentage based, meaning relative, or absolute coordinate based, in pixels. The documentation gives the reason for the relative option: when the main window size changes, the controls change size with it. If you do not want that, choose absolute coordinates. And if you have modified an interface you designed earlier, you can output only the main function or only the interface generation class, which does not affect the logic code you already wrote.

How the generated code is structured, and how you reach the widgets

Two output styles are described, and the difference matters for how you write the rest of the application.

The structured form uses a global dictionary called gComps, which holds all the GUI elements and their corresponding control variables. You access a widget with code of the form gComps["Text1Var"].set("new Text"). The object oriented form instead puts the widgets on the interface derived class as Application, so you reach them as self.widgetName.

The documentation also explains a deliberate deviation from the usual split. Most GUI frameworks put the UI part and the logic part in different files, and the logic file imports the UI file, so that changing the interface does not affect the logic. For simple programs the author prefers a single file, with the UI class and the logic class together, so that after changing the interface you can overwrite the corresponding Application_ui class and the change is done. The cost is explicit: if you add a new event callback function, you have to add it in the subclass Application as well.

For multiple interfaces, you add forms to the VB6 project and then choose which form to generate the code for.

That is the whole contract between the tool and your code. The generated part is the interface and the callback scaffolding, and your part is the logic, and the boundary is a class you can regenerate over.

The control mapping, and where it is only an approximation

The control list is long and the mapping is mostly mechanical, with a few places where the translation is not exact.

The VB6 Form maps to a Tkinter Frame for the main window, with the recommendation to set the BorderStyle property to Fixed Single or Fixed Dialog for a better result. Label behaves much the same in both, with the ability to insert a newline in the text and a wraplength property if ttk is enabled. TextBox has two Python equivalents, and the rule is that a VB6 TextBox with MultiLine=False generates an Entry and otherwise generates a Text.

Frame maps to Frame or LabelFrame depending on whether it has a Caption, and it acts as a container. CommandButton maps to Button, and the documentation points out a convenience: if the exit button has its Cancel property set to True, the generated code creates the destroy callback automatically, so you do not implement a callback yourself. Adding an ampersand before a letter in the VB6 caption binds a shortcut, Alt plus that letter, and Vb6Tkinter supports that and generates the event binding code, and the same applies to other controls with a caption such as CheckBox.

CheckBox maps to Checkbutton and OptionButton to Radiobutton. Radiobutton grouping differs between the two toolkits, and the documentation explains how Vb6Tkinter handles it: in VB6, OptionButtons inside a Frame form a group automatically, and Vb6Tkinter supports the same behaviour with Radiobuttons that share a parent, and if you want to group them manually you set the variable property of the group to the same value and give each one a distinct value, and the variable takes the value of the selected button and setting the variable selects the button.

ComboBox is the interesting case, because Tkinter has no equivalent. The closest is OptionMenu, which behaves like a ComboBox with Style set to 2, a dropdown list, so you can only choose a value from the list and cannot type one, and the advice is to write all the dropdown values into the VB6 ComboBox at design time. If the TTK theme extension library is enabled, it maps directly to the TTK Combobox, whose appearance and behaviour are basically the same.

ListBox maps to Listbox, HScrollBar and VScrollBar to Scrollbar with the orient setting deciding horizontal or vertical, and PictureBox to Canvas, which can be a container or a drawing surface.

The controls that need extra setup, and the extensions the add-in adds

Some controls in the list carry an extra requirement, and the documentation marks them in the same way.

The Slider maps to the Python Scale, the ProgressBar to Progressbar, the TreeView to Treeview, and the TabStrip to Notebook. The last three need the TTK theme extension enabled, which the documentation says is the default.

TreeView also has a heading row you can choose to show or hide, and the same scrollbar binding rule as the Listbox: create a scrollbar next to it, and if its length or height is close to that of the treeview the two are bound automatically, and if not you can pick its xscrollcommand or yscrollcommand in the add-in interface to the set method of the scrollbar.

TabStrip has the most involved procedure. Each tab page corresponds to a Frame or a PictureBox named with the TabStrip name, then a double underscore and Tab, and then a number, so for a TabStrip named TabStrip1 you create a PictureBox named TabStrip1__Tab1, with the case matching. The controls you place inside that container are added to the right tab page automatically once the code is generated. The tab page container can even be placed outside the visible area of the form, so you can shrink the IDE form to the size you actually want. The documentation warns that with relative coordinates the container size should match the TabStrip, or the controls inside will stretch or shrink to fit, which can look odd, and with absolute coordinates the container can be smaller and its controls are placed from the top left corner of the TabStrip at the design-time size. The recommendation is to use absolute coordinates when a TabStrip is involved.

The CommonDialog control is supported too, and when it is present the generated code imports the filedialog, simpledialog and colorchooser modules, which give simple file selection, input box and colour selection dialogs. It needs the Microsoft Common Dialog Control 6.0 added to the toolbox.

Then there is what the add-in adds on top of Tkinter. There is no Statusbar in Tkinter, so the add-in implements a simple one with a Label, inserted when you add a Statusbar to the VB form. There is no Tooltip property, so a simple Tooltip class is created for the matching widget when you set the ToolTipText property, and that text supports automatic wrapping or a manual newline. And the add-in hides what the documentation calls the anti-human TK mechanism for getting and setting a control's displayed value, which normally goes through the textvariable, adding setText() and text() methods to Entry, Label, Button, Checkbutton and Radiobutton so the displayed text can be set and read directly.

Where Vb6Tkinter is the wrong choice

The first limit is the one the author states himself. This is for small applications with a reasonably simple interface, and for a complex interface you should use wxPython or PyQt. The reason is structural rather than a missing feature list. The generated code is a straight translation of a form layout, and Tkinter's built-in geometry managers (pack, grid and place) are far simpler than the layout systems of larger GUI toolkits, so a form designed for a flat VB6 form does not scale into a serious interface.

The second limit is the VB6 dependency. You need a licensed, patched VB6 IDE running on a current Windows, with the AppCompat patch on Windows 10 and later, and the add-in registered as a COM component in the IDE. That is a toolchain you keep alive for the design step only, and it is a strange dependency for a Python project to carry.

The third is the fidelity of the mapping. ComboBox has no Tkinter equivalent, so it degrades to a dropdown list that you cannot type into, unless you enable the TTK extension library. Radiobutton grouping has to be emulated. The PictureBox to Canvas mapping loses some of the container behaviour. And the Scrollbar binding to a Listbox or Treeview is done by proximity rules, with a manual fallback in the add-in interface. Each of those is individually reasonable, and collectively they mean the generated code needs reading and often adjusting.

The fourth is what the add-in adds to Tkinter itself. The setText() and text() methods replace the textvariable mechanism, the Statusbar is a Label, and the Tooltip is a hand written class. Those are conveniences, and they are also a fork of the framework's conventions inside your application.

Compare that with a Python-native approach. The difference in approach is that a Python layout tool generates the same widget calls without requiring a second language, and a native toolkit gives you a real layout manager and a widget set that behaves consistently. The trade is that Vb6Tkinter gives you a comfortable drag and drop design experience that many VB6 developers already have as muscle memory, and it costs you a second toolchain and a less exact widget set.

Licence, project state and how the code is organised

Vb6Tkinter is released under the MIT licence, with the text in the LICENSE file at the repository root, which is a short and permissive file you should read yourself for the exact terms.

The release history shows steady work on the 1.x line: v1.7.2 on 2024-08-26, v1.8 on 2024-10-15 and v1.9 on 2024-12-24. The repository is not archived, and the last push was on 2026-09-27, so the tree is a few weeks old relative to today. Note the gap between the newest tag and the newest push, which tells you the code has moved on since v1.9 without a new release, and that upgrading the add-in is the file copy described in the documentation rather than a version bump.

The repository is a Visual Basic 6 project, so the tree looks like one. There is a Vb6Tkinter.vbp project file, a MainForm.frm with its .frx resource file, a Connect.cls and a Dictionary.cls, and a long list of cls* control classes, one per supported control: clsBaseControl.cls, clsButton.cls, clsCanvas.cls, clsCheckbutton.cls, clsCombobox.cls together with clsComboboxAdapter.cls, clsEntry.cls, clsForm.cls, clsLabel.cls, clsLabelFrame.cls, clsListbox.cls, clsMenu.cls and clsMenuItem.cls, clsNotebook.cls and clsNotebookTab.cls, clsOptionMenu.cls, clsProgressBar.cls, clsRadiobutton.cls, clsScale.cls, clsScrollbar.cls, clsSeparator.cls, clsSerialization.cls, clsStatusbar.cls, clsText.cls and clsTreeview.cls.

That one class per widget is the clearest statement of how the tool works. Each class knows the VB6 side of a control and its Tkinter counterpart, and the generator walks the form, asks each class what to emit, and assembles the Python file.

The rest of the tree supports the IDE side of the job. There is a Setup/ directory with the installer and the screenshots, a Patchs/ directory for the VB6 compatibility patches, Vb6Tkinter.lng for the localisation resources, MultiLanguage.bas, FontResolver.bas and Resizer.bas for the layout and font handling, a GridOcx control and its context, and forms for the about box, the file encoding dialog and the new version notification, with a separate frmOption.frm for the options.

Before you try it, the first thing to check is the control list against your own design, because the widgets that need the Microsoft Common Controls entries, the Slider, the ProgressBar and the TreeView, are exactly the ones people reach for in a small application. And budget for reading the generated Python, because the mapping is a good translation of a form, not a complete equivalent of one.

Editorial conclusion

Vb6Tkinter fits a developer who knows Tkinter but does not want to hand write layout code, and who is comfortable with Visual Basic 6 as a design tool but writes the application in Python. It does not fit a team with a large or complex interface, because the author says so himself, and it does not fit a team without a VB6 licence, since the add-in runs inside the VB6 IDE and registers itself as a COM add-in. Before you adopt it, decide whether a VB6 form designer is worth an extra runtime dependency in your toolchain, and check the control list to see whether the widgets your interface needs are covered, since some controls need extra Microsoft Common Controls entries and some behaviours are approximations rather than exact matches.

Frequently asked questions

What does the Vb6Tkinter add-in do?

It is a Visual Basic 6 add-in that lets you design a Python Tkinter interface by dragging controls on a VB6 form, set most control properties in the VB6 property grid, and generate the Python code including the callback function framework, after which you add the logic in the matching callbacks.

How do I install Vb6Tkinter?

Either download the integrated installer from the releases page, which bundles a patched slim VB6, or download the plugin archive, install VB6 yourself with the Windows 7 and Windows 10 patches, and register the plugin with Setup for Vb6Tkinter.exe or by running regsvr32 on Vb6Tkinter.dll and adding Vb6Tkinter.Connect=3 to the Add-Ins32 section of VBADDIN.INI.

Which Tkinter widgets does Vb6Tkinter support and which are only approximate?

Most Tkinter controls are covered, with Form mapping to Frame, TextBox to Entry or Text depending on MultiLine, Frame to Frame or LabelFrame, CommandButton to Button, CheckBox to Checkbutton and OptionButton to Radiobutton. ComboBox has no Tkinter equivalent, so it becomes an OptionMenu dropdown that cannot be typed into, unless the TTK theme extension library is enabled, and it then maps to the TTK Combobox.

How do I access a widget from the generated Python code?

In the structured output the tool provides a global dictionary called gComps holding all GUI elements, accessed with code like gComps["Text1Var"].set("new Text"). In the object oriented output the widgets are attributes of the interface derived class, reached as self.widgetName.

Does the Vb6Tkinter generated code keep the UI and the logic in separate files?

No, not by default. The documentation explains that the author prefers a single file for simple programs, with the UI class and the logic class together, so you can overwrite the Application_ui class after changing the interface. The cost is that a new event callback function must also be added in the subclass Application.

What licence does Vb6Tkinter use?

Vb6Tkinter is released under the MIT licence, with the terms in the LICENSE file at the repository root. The most recent release tag is v1.9 from 2024-12-24, and the last push to the repository was on 2026-09-27.

Official sources

  1. cdhigh/Vb6Tkinter on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cdhigh-vb6tkinter.svg)](https://hysenlabs.com/projects/cdhigh-vb6tkinter)

Was this useful?