Initial commit
|
|
@ -0,0 +1,4 @@
|
|||
venv
|
||||
target
|
||||
__pycache__
|
||||
*.pyc
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
altgraph==0.17
|
||||
fbs==0.9.0
|
||||
future==0.18.2
|
||||
macholib==1.14
|
||||
pefile==2019.4.18
|
||||
PyInstaller==3.4
|
||||
PyQt5==5.9.2
|
||||
sip==4.19.8
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"app_name": "Vial",
|
||||
"author": "xyz",
|
||||
"main_module": "src/main/python/main.py",
|
||||
"version": "0.0.0"
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"categories": "Utility;",
|
||||
"description": "",
|
||||
"author_email": "",
|
||||
"url": ""
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"mac_bundle_identifier": ""
|
||||
}
|
||||
|
After Width: | Height: | Size: 164 KiB |
|
|
@ -0,0 +1,11 @@
|
|||

|
||||
|
||||
This directory contains the icons that are displayed for your app. Feel free to
|
||||
change them.
|
||||
|
||||
The difference between the icons on Mac and the other platforms is that on Mac,
|
||||
they contain a ~5% transparent margin. This is because otherwise they look too
|
||||
big (eg. in the Dock or in the app switcher).
|
||||
|
||||
You can create Icon.ico from the .png files with
|
||||
[an online tool](http://icoconvert.com/Multi_Image_to_one_icon/).
|
||||
|
After Width: | Height: | Size: 544 B |
|
After Width: | Height: | Size: 783 B |
|
After Width: | Height: | Size: 912 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
|
@ -0,0 +1,131 @@
|
|||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2013 Riverbank Computing Limited.
|
||||
## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
## All rights reserved.
|
||||
##
|
||||
## This file is part of the examples of PyQt.
|
||||
##
|
||||
## $QT_BEGIN_LICENSE:BSD$
|
||||
## You may use this file under the terms of the BSD license as follows:
|
||||
##
|
||||
## "Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions are
|
||||
## met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in
|
||||
## the documentation and/or other materials provided with the
|
||||
## distribution.
|
||||
## * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
## the names of its contributors may be used to endorse or promote
|
||||
## products derived from this software without specific prior written
|
||||
## permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
## $QT_END_LICENSE$
|
||||
##
|
||||
#############################################################################
|
||||
|
||||
|
||||
from PyQt5.QtCore import QPoint, QRect, QSize, Qt
|
||||
from PyQt5.QtWidgets import (QApplication, QLayout, QPushButton, QSizePolicy,
|
||||
QWidget)
|
||||
|
||||
|
||||
class FlowLayout(QLayout):
|
||||
def __init__(self, parent=None, margin=0, spacing=-1):
|
||||
super(FlowLayout, self).__init__(parent)
|
||||
|
||||
if parent is not None:
|
||||
self.setContentsMargins(margin, margin, margin, margin)
|
||||
|
||||
self.setSpacing(spacing)
|
||||
|
||||
self.itemList = []
|
||||
|
||||
def __del__(self):
|
||||
item = self.takeAt(0)
|
||||
while item:
|
||||
item = self.takeAt(0)
|
||||
|
||||
def addItem(self, item):
|
||||
self.itemList.append(item)
|
||||
|
||||
def count(self):
|
||||
return len(self.itemList)
|
||||
|
||||
def itemAt(self, index):
|
||||
if index >= 0 and index < len(self.itemList):
|
||||
return self.itemList[index]
|
||||
|
||||
return None
|
||||
|
||||
def takeAt(self, index):
|
||||
if index >= 0 and index < len(self.itemList):
|
||||
return self.itemList.pop(index)
|
||||
|
||||
return None
|
||||
|
||||
def expandingDirections(self):
|
||||
return Qt.Orientations(Qt.Orientation(0))
|
||||
|
||||
def hasHeightForWidth(self):
|
||||
return True
|
||||
|
||||
def heightForWidth(self, width):
|
||||
height = self.doLayout(QRect(0, 0, width, 0), True)
|
||||
return height
|
||||
|
||||
def setGeometry(self, rect):
|
||||
super(FlowLayout, self).setGeometry(rect)
|
||||
self.doLayout(rect, False)
|
||||
|
||||
def sizeHint(self):
|
||||
return self.minimumSize()
|
||||
|
||||
def minimumSize(self):
|
||||
size = QSize()
|
||||
|
||||
for item in self.itemList:
|
||||
size = size.expandedTo(item.minimumSize())
|
||||
|
||||
margin, _, _, _ = self.getContentsMargins()
|
||||
|
||||
size += QSize(2 * margin, 2 * margin)
|
||||
return size
|
||||
|
||||
def doLayout(self, rect, testOnly):
|
||||
x = rect.x()
|
||||
y = rect.y()
|
||||
lineHeight = 0
|
||||
|
||||
for item in self.itemList:
|
||||
wid = item.widget()
|
||||
spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal)
|
||||
spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical)
|
||||
nextX = x + item.sizeHint().width() + spaceX
|
||||
if nextX - spaceX > rect.right() and lineHeight > 0:
|
||||
x = rect.x()
|
||||
y = y + lineHeight + spaceY
|
||||
nextX = x + item.sizeHint().width() + spaceX
|
||||
lineHeight = 0
|
||||
|
||||
if not testOnly:
|
||||
item.setGeometry(QRect(QPoint(x, y), item.sizeHint()))
|
||||
|
||||
x = nextX
|
||||
lineHeight = max(lineHeight, item.sizeHint().height())
|
||||
|
||||
return y + lineHeight - rect.y()
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
from fbs_runtime.application_context.PyQt5 import ApplicationContext
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QWidget, QTabWidget, QVBoxLayout, QPushButton, QLabel
|
||||
|
||||
import sys
|
||||
|
||||
from flowlayout import FlowLayout
|
||||
|
||||
class TabbedKeycodes(QTabWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.tab_basic = QWidget()
|
||||
layout = FlowLayout()
|
||||
|
||||
for lbl in ["", "TODO", "Esc", "A", "B", "C", "D", "E", "F"]:
|
||||
btn = QPushButton(lbl)
|
||||
btn.setFixedSize(50, 50)
|
||||
layout.addWidget(btn)
|
||||
self.tab_basic.setLayout(layout)
|
||||
|
||||
self.tab_media = QWidget()
|
||||
self.tab_macro = QWidget()
|
||||
|
||||
self.addTab(self.tab_basic, "Basic")
|
||||
self.addTab(self.tab_media, "Media")
|
||||
self.addTab(self.tab_macro, "Macro")
|
||||
|
||||
|
||||
KEY_WIDTH = 40
|
||||
KEY_HEIGHT = KEY_WIDTH
|
||||
KEY_SPACING = 10
|
||||
|
||||
|
||||
class KeyboardContainer(QWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setFixedSize(300, 300)
|
||||
|
||||
for x, btn in enumerate(["Q", "W", "E", "R"]):
|
||||
widget = QLabel(btn)
|
||||
widget.setParent(self)
|
||||
widget.setStyleSheet('background-color:red;')
|
||||
widget.setAlignment(Qt.AlignCenter)
|
||||
widget.setFixedSize(KEY_WIDTH, KEY_HEIGHT)
|
||||
widget.move((KEY_WIDTH + KEY_SPACING) * x, 0)
|
||||
|
||||
for x, btn in enumerate(["A", "S", "D", "F"]):
|
||||
widget = QLabel(btn)
|
||||
widget.setParent(self)
|
||||
widget.setStyleSheet('background-color:red;')
|
||||
widget.setAlignment(Qt.AlignCenter)
|
||||
widget.setFixedSize(KEY_WIDTH, KEY_HEIGHT)
|
||||
widget.move((KEY_WIDTH + KEY_SPACING) * (x + 0.25), KEY_HEIGHT + KEY_SPACING)
|
||||
|
||||
|
||||
class MainWindow(QWidget):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.keyboard_container = KeyboardContainer()
|
||||
|
||||
self.tabbed_keycodes = TabbedKeycodes()
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(self.keyboard_container)
|
||||
layout.addWidget(self.tabbed_keycodes)
|
||||
self.setLayout(layout)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
appctxt = ApplicationContext() # 1. Instantiate ApplicationContext
|
||||
window = MainWindow()
|
||||
window.resize(1024, 768)
|
||||
window.show()
|
||||
exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_()
|
||||
sys.exit(exit_code)
|
||||