Last active
January 12, 2016 17:42
-
-
Save LeftRadio/fca7be2a5ead949d2069 to your computer and use it in GitHub Desktop.
nla_ch_widget
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# python 3 | |
from PyQt5.QtCore import ( QSize, pyqtSlot, QPointF, Qt, pyqtProperty, | |
QByteArray, QDataStream, QIODevice, QMimeData, | |
QPoint ) | |
from PyQt5.QtWidgets import ( QFrame, QWidget, QPushButton, QLineEdit, QLayout, | |
QHBoxLayout, QVBoxLayout, QGridLayout, QSizePolicy, | |
QStyleFactory, QLabel, QListView, QListWidget, QListWidgetItem ) | |
from PyQt5.QtGui import ( QFont, QIcon, QLinearGradient, QColor, QPainter, | |
QPen, QFontMetrics, QPixmap, QDrag ) | |
from nla_ch_widget import NLA_CH_Widget | |
class NLA_CH_FrameWidget(QWidget): | |
"""docstring for NLA_CH_FrameWidget""" | |
def __init__(self, parent=None): | |
super(NLA_CH_FrameWidget, self).__init__(parent) | |
sizePolicy1 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) | |
font1 = QFont("MS Shell Dlg 2", 9) | |
font1.setBold(True) | |
lbl_title = QLabel('Logic Channels:') | |
lbl_title.setSizePolicy(sizePolicy1) | |
lbl_title.setMinimumSize(QSize(0, 20)) | |
lbl_title.setMaximumSize(QSize(16777215, 20)) | |
lbl_title.setFont(font1) | |
lbl_title.setAlignment(Qt.AlignCenter) | |
lbl_info = QLabel('Neil LA alfa 0.2') | |
lbl_info.setSizePolicy(sizePolicy1) | |
lbl_info.setMinimumSize(QSize(0, 20)) | |
lbl_info.setMaximumSize(QSize(16777215, 20)) | |
lbl_info.setFont(font1) | |
lbl_info.setAlignment(Qt.AlignCenter) | |
self.ch_frame = NLA_CH_Frame(self) | |
self.vLayout = QVBoxLayout(self) | |
self.vLayout.setSpacing(0) | |
self.vLayout.setContentsMargins(0, 0, 0, 0) | |
self.vLayout.addWidget(lbl_title) | |
self.vLayout.addWidget(self.ch_frame) | |
self.vLayout.addWidget(lbl_info) | |
@pyqtProperty(int) | |
def channels(self): | |
return len(self.ch_frame.widgets) | |
@channels.setter | |
def channels(self, val): | |
self.ch_frame.remove_all_widgets() | |
self.ch_frame.add_widgets([ NLA_CH_Widget(name="channel %s" % i) for i in range(val) ]) | |
class NLA_CH_Frame(QFrame): | |
"""docstring for NLA_CH_Frame""" | |
def __init__(self, parent=None): | |
super(NLA_CH_Frame, self).__init__(parent) | |
self.widgets = [] | |
self.channelsVLayout = QVBoxLayout(self) | |
self.channelsVLayout.setSpacing(0) | |
self.setFrameStyle(QFrame.Sunken | QFrame.StyledPanel) | |
self.setAcceptDrops(True) | |
def _set_widget_index(self, widget): | |
if widget.index == None: | |
if len(self.widgets): | |
widget.index = max([w.index for w in self.widgets]) + 1 | |
else: | |
widget.index = 0 | |
def _set_widget_def_index(self, widget): | |
if widget.def_index == None: | |
if len(self.widgets): | |
widget.def_index = max([w.def_index for w in self.widgets]) + 1 | |
else: | |
widget.def_index = 0 | |
def sort_widgets(self, **kwargv): | |
cplist = [] | |
cplist[:] = self.widgets | |
self.remove_all_widgets() | |
list = [i for i in cplist if i != None] | |
list = sorted(list, key=lambda obj: obj.index) | |
indx_reset = kwargv.get('hard', False) | |
for widget in list: | |
if indx_reset: | |
widget.index = None | |
self._set_widget_index(widget) | |
self.widgets.append(widget) | |
self.channelsVLayout.addWidget(widget) | |
def add_widget(self, widget): | |
self._set_widget_def_index(widget) | |
self._set_widget_index(widget) | |
self.widgets.append(widget) | |
self.channelsVLayout.addWidget(widget) | |
self.sort_widgets() | |
def add_widgets(self, list): | |
for item in list: | |
self.add_widget(item) | |
self.sort_widgets() | |
self.update() | |
def remove_widget(self, widget): | |
if widget in self.widgets: | |
self.widgets.remove(widget) | |
widget.setParent(None) | |
widget = None | |
self.sort_widgets() | |
def remove_all_widgets(self): | |
for w in self.widgets: | |
w.setParent(None) | |
w = None | |
self.widgets = [] | |
def get_indexPosition(self, widget, pos): | |
height = widget.size().height() | |
return pos.y() // height | |
def mousePressEvent(self, event): | |
child = self.childAt(event.pos()) | |
if not child or child not in self.widgets: | |
return | |
self.drop_widget = child | |
self.drop_widget.selected = True | |
itemData = QByteArray() | |
mimeData = QMimeData() | |
mimeData.setData('application/x-dnditemdata', itemData) | |
drag = QDrag(self) | |
drag.setMimeData(mimeData) | |
drag.setPixmap(child.pixmap) | |
drag.setHotSpot(event.pos() - child.pos()) | |
st = drag.exec_(Qt.CopyAction | Qt.MoveAction, Qt.CopyAction) | |
if st == Qt.IgnoreAction: | |
self.remove_widget(self.drop_widget) | |
self.drop_widget._def_index = None | |
self.drop_widget.index = None | |
self.add_widget(self.drop_widget) | |
self.drop_widget.selected = False | |
self.sort_widgets(hard=True) | |
def dragEnterEvent(self, event): | |
if event.mimeData().hasFormat('application/x-dnditemdata'): | |
if event.source() == self: | |
event.setDropAction(Qt.MoveAction) | |
pos_index = self.get_indexPosition(self.drop_widget, event.pos()) | |
if self.drop_widget.index != pos_index: | |
self.remove_widget(self.drop_widget) | |
self.drop_widget.index = pos_index-1 | |
self.add_widget(self.drop_widget) | |
self.sort_widgets(hard=True) | |
event.accept() | |
else: | |
event.acceptProposedAction() | |
else: | |
event.ignore() | |
dragMoveEvent = dragEnterEvent | |
def dropEvent(self, event): | |
if event.mimeData().hasFormat('application/x-dnditemdata'): | |
if event.source() == self: | |
event.setDropAction(Qt.MoveAction) | |
event.accept() | |
else: | |
event.acceptProposedAction() | |
else: | |
event.ignore() | |
# if start as app | |
if __name__ == '__main__': | |
import sys | |
from PyQt5.QtWidgets import QApplication | |
app = QApplication(sys.argv) | |
QApplication.setStyle(QStyleFactory.create('Fusion')) | |
qwidget = NLA_CH_FrameWidget() | |
qwidget.channels = 4 | |
qwidget.show() | |
sys.exit(app.exec_()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment