PYQT5 imported MDI Subwindow Scaled Up - pyqt5

I'm working on a gui tool-- I'm building it with Pyqt5. I'm speifically NOT using QT designer. I'm using an MDI widget to keep everyhing a bit tidier.
Furthermore, so that my code is more crisp and less redundant, I'm building out each child window in a separate window in the same directory and then just importing the appropriate class from the individual files.
The problem is, whenver I import the subwindows, the are scaled up in the MDI subwindow. I am at a loss as to how I can address this. Has anyone expierenced something similar? I've added simplied code for my MDI subwindow below, followed by the code for one of the subwindows thta I'm importing. Any assistance would be greatly appreciated.
Import sys
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtGui import QWindow
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import QMdiArea, QAction, QMdiSubWindow, QTextEdit
from Admission_Tool import *
from COPD_tool import *
from Discharge_Template import DischargeWindow
from Note_Template import *
class MDIWindow(QMainWindow):
count = 0
htntoolcount = 0
copdcount = 0
def __init__(self):
super().__init__()
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
self.setStyleSheet('font-size: 10pt; font-family: Times;')
self.setStyleSheet("QPushButton{font-size: 10pt;}")
self.setStyleSheet("QLabel{font-size: 10pt;}")
self.mdi.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.mdi.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
#####Setting up main Menu Labels and Buttons#####
self.mainMenuWidget = QWidget(self)
self.mmWidgetLayout = QVBoxLayout()
self.mainMenuWidget.setLayout(self.mmWidgetLayout)
self.mainMenuWidget.setWindowTitle("Main Menu")
self.mmButton1 = QPushButton("Note Setup Tool", self)
self.mmButton2 = QPushButton("Lab Entry Tool", self)
self.mmButton3 = QPushButton("Follow Up Tools", self)
self.mmButton4 = QPushButton("ROS Generator", self)
self.mmButton5 = QPushButton("Physical Exam Generator", self)
self.mmButton6 = QPushButton("Cardon Matrix", self)
self.mmButton7 = QPushButton("Trilogy Matrix", self)
self.mmButton8 = QPushButton("ASC Matrix", self)
self.mmButton9 = QPushButton("Proactive Email", self)
self.mmWidgetLayout.addWidget(self.mmButton1)
self.mmWidgetLayout.addWidget(self.mmButton2)
self.mmWidgetLayout.addWidget(self.mmButton3)
self.mmWidgetLayout.addWidget(self.mmButton4)
self.mmWidgetLayout.addWidget(self.mmButton5)
self.mmWidgetLayout.addWidget(self.mmButton6)
self.mmWidgetLayout.addWidget(self.mmButton7)
self.mmWidgetLayout.addWidget(self.mmButton8)
self.mmWidgetLayout.addWidget(self.mmButton9)
self.mdi.addSubWindow(self.mainMenuWidget)
self.mainMenuWidget.show()
##adding actions to main menu buttons##
self.mmButton1.clicked.connect(self.noteSetupFunc)
self.mmButton2.clicked.connect(self.admissionTool)
self.mmButton3.clicked.connect(self.COPDToolFunc)
self.setWindowTitle("Proactive Charting Tool")
def noteSetupFunc(self):
self.noteSUButtFuncWidget = NOTEWindow()
self.mdi.addSubWindow(self.noteSUButtFuncWidget)
self.noteSUButtFuncWidget.show()
# Setting MAin Menu Widget for NOtes#
# self.NOTEmainMenuWidget = QWidget(self)
# self.noteMMWidgetLayout = QVBoxLayout()
# self.NOTEmainMenuWidget.setLayout(self.noteMMWidgetLayout)
# self.NOTEmainMenuWidget.setWindowTitle("Note Menu")
#
# self.NotemmButton1 = QPushButton("Admission", self)
# self.NotemmButton2 = QPushButton("Discharge", self)
# self.NotemmButton3 = QPushButton("Diag Testing", self)
# self.NotemmButton4 = QPushButton("Acute Visit", self)
# self.NotemmButton5 = QPushButton("Fall", self)
# self.NotemmButton6 = QPushButton("Med Review / Comp", self)
# self.NotemmButton7 = QPushButton("Coumadin", self)
# self.NotemmButton8 = QPushButton("Noncompliance", self)
# self.NotemmButton9 = QPushButton("Simple Note", self)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton1)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton2)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton3)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton4)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton5)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton6)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton7)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton8)
# self.noteMMWidgetLayout.addWidget(self.NotemmButton9)
# self.mdi.addSubWindow(self.NOTEmainMenuWidget)
# self.NOTEmainMenuWidget.show()
# self.NOTEMMButton2.clicked.connect(self.dcwindowFunc)
def admissionTool(self):
self.admitToolWidget = admitWindow()
self.mdi.addSubWindow(self.admitToolWidget)
self.admitToolWidget.show()
def COPDToolFunc(self):
self.copdToolWidget = COPDWindow()
self.mdi.addSubWindow(self.copdToolWidget)
self.copdToolWidget.show()
MDIWindow.copdcount = MDIWindow.copdcount + 1
def dcwindowFunc(self):
self.dcwindowWidget = DischargeWindow()
self.mdi.addSubWindow(self.dcwindowWidget)
self.dcwindowWidget.show()
def htnButton(self):
self.htnsubwidgets = QWidget(self)
self.htnMAinLayout = QHBoxLayout()
self.htnLeftLayout = QVBoxLayout()
self.htnRightLayout = QVBoxLayout()
##Adding secondary layours to main layouts##
self.htnMAinLayout.addLayout(self.htnLeftLayout)
self.htnMAinLayout.addLayout(self.htnRightLayout)
##Adding htnRightLayout widgets##
self.htnLabel1 = QLabel("Date of last HTN Med change", self)
self.htnDateEdit = QDateEdit(self)
self.htnDateEdit.setGeometry(QtCore.QRect(10, 30, 120, 45))
self.htnDateEdit.setObjectName("Med_change_dateEdit")
self.htnDateEdit.setDate(QtCore.QDate.currentDate())
self.htnDateEdit.setCalendarPopup(True)
self.htnQ2Label = QLabel("Med most recently changed?", self)
self.htnQ2LineEdit = QLineEdit()
self.htnQ3Label = QLabel("Most Recent bP Measurement", self)
self.htnQ3LineEdit = QLineEdit()
self.htnQ4Label = QLabel("Overall Bp Control?", self)
self.htnQ4Combobox = QComboBox()
self.htnQ4ComboboxList = ["Hypotension", "BP Well Controlled", "Some Hypertensive Episodes",
"Regular Hypertension"]
self.htnQ4Combobox.addItems(self.htnQ4ComboboxList)
self.htnq5Label = QLabel("Resident's current meds?", self)
self.htnq5LineEdit = QLineEdit()
self.htnCompleteButton = QPushButton("Complete", self)
self.htnCompleteButton.setMaximumWidth(75)
##Adding Widgets to Left Layout##
self.htnLeftLayout.addWidget(self.htnLabel1)
self.htnLeftLayout.addWidget(self.htnDateEdit)
self.htnLeftLayout.addWidget(self.htnQ2Label)
self.htnLeftLayout.addWidget(self.htnQ2LineEdit)
self.htnLeftLayout.addWidget(self.htnQ3Label)
self.htnLeftLayout.addWidget(self.htnQ3LineEdit)
self.htnLeftLayout.addWidget(self.htnQ4Label)
self.htnLeftLayout.addWidget(self.htnQ4Combobox)
self.htnLeftLayout.addWidget(self.htnq5Label)
self.htnLeftLayout.addWidget(self.htnq5LineEdit)
self.htnLeftLayout.addWidget(self.htnCompleteButton)
## Adding right widgets##
self.htntextedit = QTextEdit()
self.htntextedit.setMinimumWidth(200)
##Adding right widgets##
self.htnRightLayout.addWidget(self.htntextedit)
self.htnCompleteButton.clicked.connect(self.htnCompleteFunc)
self.htnsubwidgets.setLayout(self.htnMAinLayout)
self.mdi.addSubWindow(self.htnsubwidgets)
self.htnsubwidgets.show()
def htnCompleteFunc(self):
self.htnTotalList = [self.htnDateEdit.text(),self.htnQ2LineEdit.text(),self.htnQ3LineEdit.text(),self.htnQ4Combobox.currentText(),self.htnq5LineEdit.text()]
self.htntextedit.setText(f"The resient's most recent blood pressure med change ({self.htnTotalList[0]}) change was {self.htnTotalList[1]}. The residnet's most recent BP is {self.htnTotalList[2]}. The resdient is currently receiving {self.htnTotalList[4]}. Overall hypertension status: {self.htnTotalList[3]}")
def main():
app = QApplication(sys.argv)
font = QFont('Times', 10)
app.setFont(font)
mdiwindow = MDIWindow()
mdiwindow.show()
app.exec_()
if __name__ == '__main__':
main()ere
An example of one of my subwindowss is as follows:
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import QMdiArea, QAction, QMdiSubWindow, QTextEdit
from Admission_Tool import *
from COPD_tool import *
class NOTEWindow(QWidget):
def __init__(self):
super().__init__()
self.notemdi = QWidget()
self.setStyleSheet('font-size: 10pt; font-family: Times;')
self.setStyleSheet("QPushButton{font-size: 10pt;}")
self.setStyleSheet("QLabel{font-size: 10pt;}")
self.notemdi.setMaximumSize(500,500)
#Setting MAin Menu Widget for this nested MDI#
self.NOTEmainMenuWidget = QWidget(self)
self.noteMMWidgetLayout = QVBoxLayout()
self.NOTEmainMenuWidget.setLayout(self.noteMMWidgetLayout)
self.NOTEmainMenuWidget.setWindowTitle("Note Menu")
self.mmButton1 = QPushButton("Admission", self)
self.mmButton2 = QPushButton("Discharge", self)
self.mmButton3 = QPushButton("Diagnostic Testing", self)
self.mmButton4 = QPushButton("Acute Visit", self)
self.mmButton5 = QPushButton("Fall", self)
self.mmButton6 = QPushButton("Med Review/Comp", self)
self.mmButton7 = QPushButton("Coumadin", self)
self.mmButton8 = QPushButton("Noncompliance", self)
self.mmButton9 = QPushButton("Weight Loss", self)
self.mmButton10 = QPushButton("Simple Note",self)
self.noteMMWidgetLayout.addWidget(self.mmButton1)
self.noteMMWidgetLayout.addWidget(self.mmButton2)
self.noteMMWidgetLayout.addWidget(self.mmButton3)
self.noteMMWidgetLayout.addWidget(self.mmButton4)
self.noteMMWidgetLayout.addWidget(self.mmButton5)
self.noteMMWidgetLayout.addWidget(self.mmButton6)
self.noteMMWidgetLayout.addWidget(self.mmButton7)
self.noteMMWidgetLayout.addWidget(self.mmButton8)
self.noteMMWidgetLayout.addWidget(self.mmButton9)
self.noteMMWidgetLayout.addWidget(self.mmButton10)
self.NOTEmainMenuWidget.show()
def main():
app = QApplication(sys.argv)
font = QFont('Times', 10)
app.setFont(font)
mdiwindow = NOTEWindow()
mdiwindow.show()
app.exec_()
if __name__ == '__main__':
main()

Related

Drag and Drop not working in `QFileModelSystem`

I'm trying to make a drag and drop behavior in QFileSystemModel but because I have no experience in making a drag and drop before, I tried it first on QTreeView. (I attached the video of the behavior)
Now that I'm fine with the behavior I want, I then just changed the model to QFileSystemModel but sadly It's not working. So I tried to read the QFileSystemModel, QTreeView, and Drag and Drop from Qt and I ended up with the code below:
The code I ended up with:
import os
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class MQTreeView(QTreeView):
def __init__(self, model):
super().__init__()
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
# self.setDragDropMode(QAbstractItemView.InternalMove)
self.setModel(model)
self.setDragDropMode(QAbstractItemView.DragDrop)
self.setRootIndex(model.index(os.path.dirname(os.path.abspath("__file__"))))
self.setDefaultDropAction(Qt.MoveAction)
self.viewport().setAcceptDrops(True)
def dragEnterEvent(self, event):
m = event.mimeData()
if m.hasUrls():
event.accept()
return
event.ignore()
# return super().dragEnterEvent(event)
def dropEvent(self, event):
print("[drop event] - dropped")
if event.source():
QTreeView.dropEvent(self, event)
else:
ix = self.indexAt(event.pos())
model = self.model()
if ix.isValid():
if not model.isDir(ix):
ix = ix.parent() # In case of folder/Dir
pathDir = model.filePath(ix)
else:
# for empty drag and drop
pathDir = model.rootPath()
m = event.mimeData()
if m.hasUrls():
urlLocals = [url for url in m.urls() if url.isLocalFile()]
accepted = False
for urlLocal in urlLocals:
path = urlLocal.toLocalFile()
info = QFileInfo(path)
n_path = QDir(pathDir).filePath(info.fileName())
o_path = info.absoluteFilePath()
if n_path == o_path:
continue
if info.isDir():
QDir().rename(o_path, n_path)
else:
qfile = QFile(o_path)
if QFile(n_path).exists():
n_path += "(copy)"
qfile.rename(n_path)
print(f"added -> {info.fileName()}")
accepted = True
if accepted:
event.acceptProposedAction()
# return super().dropEvent(event)
class AppDemo(QWidget):
def __init__(self):
super().__init__()
# -- right -- #
self.model1 = QFileSystemModel()
self.model1.setRootPath(os.path.dirname(os.path.abspath("__file__")))
self.view1 = MQTreeView(self.model1)
# -- left -- #
self.model2 = QFileSystemModel()
self.model2.setRootPath(os.path.dirname(os.path.abspath("__file__")))
self.view2 = MQTreeView(self.model2)
# -- layout -- #
layout = QHBoxLayout(self)
layout.addWidget(self.view1)
layout.addWidget(self.view2)
app = QApplication(sys.argv)
main = AppDemo()
main.show()
app.exec_()
The code above is still not doing the behavior I want but I'm pretty sure that something else is wrong and it is not with the overridden function (dragEnterEvent and dropEvent). My best guess is that I didn't set properly the correct way QTreeView accepts the drops although I'm not really sure.
My Question: What is wrong with my Implementation? Is it the way I accept drops or it is something else?
Found what's wrong! I didn't override the dragMoveEvent method. I need to override the dragMoveEvent to make sure that the drag will not be forbidden.
I need to accept all drag event in the dragEnterEvent:
def dragEnterEvent(self, event):
event.accept()
Then I need to filter the events in the dragMoveEvent:
def dragMoveEvent(self, event):
m = event.mimeData()
if m.hasUrls():
event.accept()
print("[dropEnterEvent] - event accepted")
return
event.ignore()
I attached the video and code of the working behavior below.
The final implementation:
import os
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class MQTreeView(QTreeView):
def __init__(self, model, path):
super().__init__()
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.setModel(model)
self.setDragDropMode(QAbstractItemView.DragDrop)
self.setRootIndex(model.index(path))
self.setDefaultDropAction(Qt.MoveAction)
self.viewport().setAcceptDrops(True)
def dragEnterEvent(self, event):
event.accept()
def dragMoveEvent(self, event):
m = event.mimeData()
if m.hasUrls():
event.accept()
print("[dropEnterEvent] - event accepted")
return
event.ignore()
def dropEvent(self, event):
print("[drop event] - dropped")
if event.source():
ix = self.indexAt(event.pos())
model = self.model()
if ix.isValid():
if not model.isDir(ix):
ix = ix.parent()
pathDir = model.filePath(ix)
else:
# for empty drag and drop
pathDir = model.rootPath()
m = event.mimeData()
if m.hasUrls():
urlLocals = [url for url in m.urls() if url.isLocalFile()]
accepted = False
for urlLocal in urlLocals:
path = urlLocal.toLocalFile()
info = QFileInfo(path)
destination = QDir(pathDir).filePath(info.fileName())
source = info.absoluteFilePath()
if destination == source:
continue # means they are in the same folder
if info.isDir():
QDir().rename(source, destination)
else:
qfile = QFile(source)
if QFile(destination).exists():
n_info = QFileInfo(destination)
destination = n_info.canonicalPath() + QDir.separator() + n_info.completeBaseName() + " (copy)"
if n_info.completeSuffix(): # for moving files without suffix
destination += "." + n_info.completeSuffix()
qfile.rename(destination)
print(f"added -> {info.fileName()}") # for debugging
accepted = True
if accepted:
event.acceptProposedAction()
class AppDemo(QWidget):
def __init__(self):
super().__init__()
self.setAcceptDrops(True)
cwd = "test/"
nw = "test copy/"
# -- right -- #
self.model1 = QFileSystemModel()
self.model1.setRootPath(os.path.dirname(cwd))
self.view1 = MQTreeView(self.model1, cwd)
# -- left -- #
self.model2 = QFileSystemModel()
self.model2.setRootPath(os.path.dirname(nw))
self.view2 = MQTreeView(self.model2, nw)
# -- layout -- #
layout = QHBoxLayout(self)
layout.addWidget(self.view1)
layout.addWidget(self.view2)
app = QApplication(sys.argv)
main = AppDemo()
main.show()
app.exec_()

how to make copy paste to follow the same pattern

I am creating a design with my QGraphicsitems . I have selected all the items in the scene and pasted it.But it is not following the same pattern.can we make the items paste in the same pattern like the one which we have created initially? –
I have tried with the following code
from PyQt5.QtCore import (QByteArray,QDataStream, QIODevice,pyqtSlot, QMimeData, QPointF, QPoint, Qt, QRect,QTimer,QLineF, QEvent,QRectF)
from PyQt5.QtGui import QColor,QDrag, QPainter, QPixmap,QFont,QFontMetrics,QBrush, QLinearGradient, QIcon, QPen, QPainterPath, QTransform,QCursor,QMouseEvent,QClipboard
from PyQt5.QtWidgets import QApplication,QGraphicsTextItem,QGraphicsItemGroup, QSizePolicy,QShortcut, QScrollArea, QPushButton,QLineEdit, QMainWindow,QInputDialog, QGraphicsPathItem,QDialog, QVBoxLayout,QGraphicsItem,QStatusBar,QTextEdit, QAction,QMenu, qApp,QSplitter, QButtonGroup, QToolButton, QFrame, QHBoxLayout, QGraphicsView, QGraphicsItem, QGraphicsPixmapItem, QLabel, QGraphicsScene, QWidget
import importlib
import SketchBook as sketchBook
import Blocks as blocks
import random
custom_mimeType = "application/x-qgraphicsitems"
pos1 = QPointF()
def item_to_ds(it, ds):
if not isinstance(it, QGraphicsItem):
return
ds.writeQString(it.__class__.__module__)
ds.writeQString(it.__class__.__name__)
ds.writeInt(it.flags())
ds << it.pos()
posdiff = it.pos().x() -pos1().x()
pos1 = QPointF(it.pos().x(),it.pos().y())
# ds.writeInt(it.UserType)
ds.writeFloat(it.opacity())
ds.writeFloat(it.rotation())
ds.writeFloat(it.scale())
# ds.writeString(it.type())
# ds.writeQString(it.type1())
# if isinstance(it, QGraphicsItem):
# ds << it.brush() << it.pen()
if isinstance(it, QGraphicsPixmapItem):
ds << it.pixmap()
if isinstance(it, QGraphicsPathItem):
ds << it.path()
def ds_to_item(ds):
module_name = ds.readQString()
class_name = ds.readQString()
if class_name == 'QGraphicsPixmapItem':
mod = importlib.import_module(module_name)
it = getattr(mod, class_name)()
# flags = QGraphicsItem.GraphicsItemFlag(ds.readInt())
# pos = QPointF()
# ds >> pos
# it.setFlags(flags)
# it.setPos(pos)
# it.setOpacity(ds.readFloat())
# it.setRotation(ds.readFloat())
# it.setScale(ds.readFloat())
else:
mod = importlib.import_module(module_name)
it = getattr(mod, class_name)(blocks.selectedObjType)
flags = QGraphicsItem.GraphicsItemFlag(ds.readInt())
pos = QPointF()
ds >> pos
it.setFlags(flags)
it.setPos(pos)
it.setOpacity(ds.readFloat())
it.setRotation(ds.readFloat())
it.setScale(ds.readFloat())
# if isinstance(it, QGraphicsItem):
# pen, brush = QPen(), QBrush()
# ds >> brush
# ds >> pen
# it.setPen(pen)
# it.setBrush(brush)
if isinstance(it, QGraphicsPathItem):
path = QPainterPath()
ds >> path
it.setPath(path)
if isinstance(it, QGraphicsPixmapItem):
pixmap = QPixmap()
# pen, brush = QPen(), QBrush()
# ds >> brush
# ds >> pen
ds >> pixmap
it.setPixmap(pixmap)
return it
class GraphicsSceneClass(QGraphicsScene):
global selectedObjType
def __init__(self, parent=None):
super(GraphicsSceneClass, self).__init__(parent)
self.gridOn = 0
self.setSceneRect(0, 0, 1920, 1080)
self.setItemIndexMethod(QGraphicsScene.NoIndex)
self.setBackgroundBrush(QBrush(Qt.black))
def mousePressEvent(self, event):
sampleTransform = QTransform()
objectAtMouse = self.itemAt(event.scenePos(), sampleTransform)
if objectAtMouse and event.button()== Qt.LeftButton:
objectAtMouse.setSelected(True)
elif objectAtMouse==None and event.button()==Qt.RightButton:
# pass
self.grid = self.TargPosForLine(event.scenePos(), "ForLine")
self.grid = self.TargPosForLine(event.scenePos(), "ForLine")
print(self.grid)
# else:
# self.DeselectItems()
# objectAtMouse.QShortcut
def TargPosForLine(self, position, mode):
clicked_column = int((position.y() // 16)) * 16
clicked_row = int((position.x() // 16)) * 16
if clicked_column < 0:
clicked_column = 0
if clicked_row < 0:
clicked_row = 0
if(mode == "ForRect"):
return QRect(clicked_row, clicked_column,16,16)
elif(mode == "ForLine"):
return QPointF(clicked_row,clicked_column)
def DeselectItems(self):
selectedObjects = self.selectedItems()
for object in selectedObjects:
object.setSelected(False)
def mouseReleaseEvent(self, event):
# self.DeselectItems()
pass
class MainWindow(QMainWindow):
global selectedObjType
# global item
def __init__(self,):
super(MainWindow, self).__init__()
self.createActions()
self.createMenus()
self.createToolbars()
self.scene = GraphicsSceneClass()
MainWindow.obj = self.scene
self.view = QGraphicsView(self.scene)
# self.view.setDragMode(QGraphicsView.RubberBandDrag)
self.view.setMouseTracking(True)
self.view.setRenderHint(QPainter.HighQualityAntialiasing)
self.widg = QWidget()
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.addWidget(self.view)
self.widg.setMouseTracking(True)
self.widget = QWidget()
self.widget.setLayout(self.horizontalLayout)
self.setCentralWidget(self.widget)
self.obj=None
def createMenus(self):
menuBar = self.menuBar()
fileMenu = menuBar.addMenu('&File')
fileMenu.addAction(self.exitAction)
fileMenu = menuBar.addMenu('&Edit')
fileMenu.addAction(self.copyAction)
fileMenu.addAction(self.pasteAction)
fileMenu.addAction(self.selectAction)
def createActions(self):
self.exitAction = QAction("E&xit", self, shortcut="Ctrl+X", statusTip="Quit Scenediagram example",
triggered=self.deleteItem)
self.copyAction = QAction("C&opy", self, shortcut="Ctrl+C", triggered=self.copy)
self.pasteAction = QAction("P&aste", self, shortcut="Ctrl+V", triggered=self.paste)
self.selectAction = QAction("S&electAll", self, shortcut="Ctrl+A", triggered=self.selectAll)
def createToolbars(self):
GridButton = QToolButton()
GridButton.setCheckable(True)
GridButton.setIcon(QIcon('images/GridButton.png'))
GridButton.clicked.connect(self.GridOnOffControl)
GridButton.setToolTip("Grid Control")
self.pointerToolbar = self.addToolBar("Pointer type")
self.pointerToolbar.addWidget(GridButton)
def deleteItem(self):
for item in self.scene.selectedItems():
self.scene.removeItem(item)
def selectAll(self):
for item in self.scene.items():
item.setSelected(True)
def GridOnOffControl(self):
if self.scene.gridOn == 0:
self.scene.gridOn = 1
else:
self.scene.gridOn = 0
if self.scene.gridOn == 1:
self.scene.setBackgroundBrush(QBrush(QPixmap('images/Grid.png')))
else:
self.scene.setBackgroundBrush(QBrush(Qt.black))
def contextMenuEvent(self, event):
contextMenu = QMenu(self)
Cutaction = contextMenu.addAction("Cut")
Coaction = contextMenu.addAction("Copy")
Paaction = contextMenu.addAction("Paste")
Propaction = contextMenu.addAction("draw1")
Propaction1=contextMenu.addAction("draw2")
quitAct = contextMenu.addAction("quit")
action = contextMenu.exec_(self.mapToGlobal(event.pos()))
if action == quitAct:
self.close()
elif action == Propaction:
objectDrop = None
# painterPath = QPainterPath()
#
# painterPath.moveTo(10, 50.0)
# painterPath.lineTo(50,50)
# painterPath.lineTo(50,55)
# painterPath.lineTo(10,55)
# gradient = QLinearGradient(1, 1, 1, 5)
# gradient.setColorAt(0, QColor(Qt.gray))
# gradient.setColorAt(0.5, QColor(192, 192, 192, 255))
# gradient.setColorAt(1, QColor(Qt.darkGray))
# painterPath.closeSubpath()
#
# objectDrop = QGraphicsPathItem()
# objectDrop.setPath(painterPath)
# objectDrop.setBrush(QBrush(gradient))
objectDrop = QGraphicsPixmapItem(QPixmap("2AS_HG_RG.png"))
objectDrop.setPos(self.scene.grid)
print("sig",self.scene.grid)
# objectDrop._position = QPointF(gridPos.x() + 2, gridPos.y() + 5.9)
# objectDrop._type = "2AS_HG_RG"
objectDrop._type1 = "2AS_HG_RG"
self.scene.addItem(objectDrop)
objectDrop.setFlag(QGraphicsItem.ItemIsSelectable)
objectDrop.setFlag(QGraphicsItem.ItemIsMovable)
objectDrop._type1="2AS_HG_RG"
# self.scene.addPath(painterPath)
elif action==Propaction1:
objectDrop = None
selectedObjType = "line"
objectDrop = sketchBook.SketchBook(selectedObjType)
print("line",self.scene.grid)
objectDrop.setFlag(QGraphicsItem.ItemIsSelectable)
objectDrop.setFlag(QGraphicsItem.ItemIsMovable)
objectDrop._type1 = "line"
objectDrop.setPos(self.scene.grid.x(),self.scene.grid.y()-48+5)
self.scene.addItem(objectDrop)
elif action == Coaction:
self.copy()
elif action == Paaction:
self.paste()
#pyqtSlot()
def copy(self):
mimedata = QMimeData()
ba = QByteArray()
ds = QDataStream(ba, QIODevice.WriteOnly)
for it in self.scene.selectedItems():
self.posdiff=item_to_ds(it, ds)
mimedata.setData(custom_mimeType, ba)
clipboard = QApplication.clipboard()
clipboard.setMimeData(mimedata)
#pyqtSlot()
def paste(self):
pos2=self.scene.grid
clipboard = QApplication.clipboard()
mimedata = clipboard.mimeData()
if mimedata.hasFormat(custom_mimeType):
ba = mimedata.data(custom_mimeType)
# STR = str(ba)
# QW = ba.capacity()
ds = QDataStream(ba)
while not ds.atEnd():
# for it in ds:
it = ds_to_item(ds)
if isinstance(it, QGraphicsPixmapItem):
self.scene.addItem(it)
it.setPos(pos2)
it._position = QPointF(pos2.x() + 2, pos2.y() + 5.9)
print("sig",it._position)
it._type1 = "2AS_HG_RG"
else:
gradient = QLinearGradient(1, 1, 1, 5)
gradient.setColorAt(0, QColor(Qt.gray))
gradient.setColorAt(0.5, QColor(192, 192, 192, 255))
gradient.setColorAt(1, QColor(Qt.darkGray))
self.scene.addItem(it)
it.setBrush(QBrush(gradient))
it.setPos(pos2.x()+self.posdiff().x(),pos2.y()-48)
it._position = QPointF(pos2.x() + 2, pos2.y() + 5.9)
print(it._position)
# it.setFlags(QGraphicsItem.ItemIsSelectable)
# it._type1 = "line"
def selectedItem(self):
items = self.scene.selectedItems()
if len(items) == 1:
return items[0]
return None
if __name__=="__main__":
import sys
app=QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
1) select all the items or the items to be pasted
2) copy it
3) paste it
if we have design pattern have item1 followed by item2 followed by item3 with respective distance. When we copy and paste it it should follow the same pattern.
QGraphicsItem.setPos() is absolute to the scene (or relative to its parent), the alternative solution is to use moveBy(x, y) (which is the same as setPos(self.pos() + deltaPos), but you have to take into account the relative position of the click according to the reference point.
I'd suggest you to not set the position until all items have been added, and then set their position according to a specific item that will be used as an "anchor" point.
#pyqtSlot()
def paste(self):
pos2=self.scene.grid
clipboard = QApplication.clipboard()
mimedata = clipboard.mimeData()
items = []
topLeft = None
if mimedata.hasFormat(custom_mimeType):
ba = mimedata.data(custom_mimeType)
ds = QDataStream(ba)
while not ds.atEnd():
it = ds_to_item(ds)
items.append(it)
if not topLeft:
topLeft = it
elif it.y() < topLeft.y() or it.x() < topLeft.x():
# find a possible topmost/leftmost item
topLeft = it
# add items, but do not set their position here
# ...
delta = self.scene.grid - topLeft.pos()
[i.moveBy(delta.x(), delta.y()) for i in items]
An alternative is to find the "anchor" in the copy procedure, and set the position of each item relative to that point in the datastream, so that you'll be able to use moveBy(pos2.x(), pos2.y()) directly after adding the items.

PyQt5: detect a new inserted tab with QTabWidget::tabInserted(int index)

I'm new in PyQt5. I made a tabWidget where I was able to connect a button to add tabs dynamically and remove/close them. Before inserting tabs with button.Clicked, there's one open (already inserted) tab saying "no tabs are open". I would like to close this tab after inserting a new tab and reopen the tab after closing all new tabs (when no tabs are open). I couldn't find any example on how to use QTabWidget::tabInserted(int index) from http://doc.qt.io/qt-5/qtabwidget.html. Does anyone know how to use tabInserted and tabRemoved to detect when triggered. I would like to increment each time a tab is inserted and decrement when removed, to know when there are open tabs and no open tabs. Thanks
self.toolButton.clicked.connect(self.button_addtab)
self.tabWidget.tabCloseRequested.connect(self.close_tab)
def button_addtab(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.tabWidget.setCurrentIndex(pages-0)
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Second_tab"))
def close_tab(self, index):
self.tabWidget.removeTab(index)
I tried this:
if self.tabWidget.count() <= 0:
#Add the "no tab open" tab
self.tab_3 = QtWidgets.QWidget()
self.tab_3.setObjectName("tab_3")
self.tabWidget.addTab(self.tab_3, "")
_translate = QtCore.QCoreApplication.translate
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Info"))
elif self.tabWidget.count() > 0:
self.tabWidget.removeTab(self.tabWidget.indexOf(self.tab_3))
This work, but it doesn't add after closing and it reopens after one more tab is added. That's why I would like to use tabInserted
See class TabWidget
import sys
from PyQt5.QtCore import Qt, QRect
from PyQt5.QtGui import QColor, QPainter
from PyQt5.QtWidgets import (QApplication, QWidget, QMainWindow, QAction,
QVBoxLayout, QTabWidget, QFileDialog, QPlainTextEdit, QHBoxLayout)
lineBarColor = QColor(53, 53, 53)
lineHighlightColor = QColor('#00FF04')
class TabWidget(QTabWidget):
def __init__(self, parent=None):
super(TabWidget, self).__init__(parent)
# This virtual handler is called after a tab was removed from position index.
def tabRemoved(self, index):
print("\n tab was removed from position index -> {}".format(index))
# This virtual handler is called after a new tab was added or inserted at position index.
def tabInserted(self, index):
print("\n New tab was added or inserted at position index -> {}".format(index))
class NumberBar(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.editor = parent
layout = QVBoxLayout(self)
self.editor.blockCountChanged.connect(self.update_width)
self.editor.updateRequest.connect(self.update_on_scroll)
self.update_width('001')
def mousePressEvent(self, QMouseEvent):
print("\n - class NumberBar(QWidget): \n\tdef mousePressEvent(self, QMouseEvent):")
def update_on_scroll(self, rect, scroll):
if self.isVisible():
if scroll:
self.scroll(0, scroll)
else:
self.update()
def update_width(self, string):
width = self.fontMetrics().width(str(string)) + 10
if self.width() != width:
self.setFixedWidth(width)
def paintEvent(self, event):
if self.isVisible():
block = self.editor.firstVisibleBlock()
height = self.fontMetrics().height()
number = block.blockNumber()
painter = QPainter(self)
painter.fillRect(event.rect(), lineBarColor)
painter.setPen(Qt.white)
painter.drawRect(0, 0, event.rect().width() - 1, event.rect().height() - 1)
font = painter.font()
current_block = self.editor.textCursor().block().blockNumber() + 1
while block.isValid():
block_geometry = self.editor.blockBoundingGeometry(block)
offset = self.editor.contentOffset()
block_top = block_geometry.translated(offset).top()
number += 1
rect = QRect(0, block_top, self.width() - 5, height)
if number == current_block:
font.setBold(True)
else:
font.setBold(False)
painter.setFont(font)
painter.drawText(rect, Qt.AlignRight, '%i' % number)
if block_top > event.rect().bottom():
break
block = block.next()
painter.end()
class Content(QWidget):
def __init__(self, text):
super(Content, self).__init__()
self.editor = QPlainTextEdit()
self.editor.setPlainText(text)
# Create a layout for the line numbers
self.hbox = QHBoxLayout(self)
self.numbers = NumberBar(self.editor)
self.hbox.addWidget(self.numbers)
self.hbox.addWidget(self.editor)
class MyTableWidget(QWidget):
def __init__(self, parent=None):
super(QWidget, self).__init__(parent)
self.layout = QVBoxLayout(self)
# Initialize tab screen
self.tabs = TabWidget() #QTabWidget()
self.tabs.resize(300, 200)
# Add tabs
self.tabs.setTabsClosable(True)
self.tabs.tabCloseRequested.connect(self.closeTab)
# Add tabs to widget
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
def closeTab(self, index):
tab = self.tabs.widget(index)
tab.deleteLater()
self.tabs.removeTab(index)
def addtab(self, content, fileName):
self.tabs.addTab(Content(str(content)), str(fileName))
class Main(QMainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.open()
self.tabs = MyTableWidget()
self.setCentralWidget(self.tabs)
self.initUI()
self.show()
def initUI(self):
self.statusBar()
menu = self.menuBar()
fileMenu = menu.addMenu('File')
fileMenu.addAction(self.openAct)
self.resize(800, 600)
def closeTab(self, index):
tab = self.tabs.widget(index)
tab.deleteLater()
self.tabs.removeTab(index)
def buttonClicked(self):
self.tabs.addTab(Content("smalltext2"), "sadsad")
def open(self):
self.openAct = QAction('Open...', self)
self.openAct.setShortcut('Ctrl+O')
self.openAct.setStatusTip('Open a file')
self.is_opened = False
self.openAct.triggered.connect(self.openFile)
def openFile(self):
options = QFileDialog.Options()
filenames, _ = QFileDialog.getOpenFileNames(
self, 'Open a file', '',
'Python Files (*.py);;Text Files (*.txt)',
options=options
)
if filenames:
for filename in filenames:
with open(filename, 'r+') as file_o:
try:
text = file_o.read()
self.tabs.addtab(text, filename)
except Exception as e:
print("Error: filename=`{}`, `{}` ".format( filename, str(e)))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Main()
sys.exit(app.exec_())

Set different background color in specific rows in QTableview

Hello, how i can change the background color in specific rows in QTableview?
I would like to know which method to use to make.
I have the method seleckRow but click another the color is not maintained in the selected row.
__author__ = 'jordiponsisala'
import sys
from PyQt5.QtWidgets import QDialog, QApplication
from PyQt5.QtSql import *
from PyQt5 import QtWidgets
from Llistats import modificarLineal
def crearConeccio():
db = QSqlDatabase.addDatabase("QMYSQL")
db.setHostName("localhost")
db.setDatabaseName("ProvaDB")
db.setUserName("root")
db.setPassword("password")
db.open()
print (db.lastError().text())
return True
class clasArticles(QDialog, modificarLineal.Ui_Dialog):
def __init__(self, parent=None):
super(clasArticles, self).__init__(parent)
self.setupUi(self)
self.setWindowTitle('Posu el nom que vulgui')
self.model= QSqlRelationalTableModel(self)
self.model.setTable('preu')
#self.model.setEditStrategy(QSqlRelationalTableModel.OnFieldChange)
self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
self.model.setRelation(2,QSqlRelation("probeedors", "id", "nomProbeedor"))
self.model.select()
self.tableView.setModel(self.model)
self.tableView.setItemDelegate(QSqlRelationalDelegate(self.model))
self.tableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.tableView.selectRow(1)
self.filtrarLineal.clicked.connect(self.filtrarRecords)
self.cancelarLineal.clicked.connect(self.cancelRecords)
self.afegirLineal.clicked.connect(self.insertRecords)
self.eliminarLineal.clicked.connect(self.deleteRecords)
self.seleccionar.clicked.connect(self.seleccionarCodi)
self.tableView.doubleClicked.connect(self.probes_index)
self.tableView.activated.connect(self.actualitzarRecords)# Pres intro method
def probes_index(self):# metod for print index in row
indexes = self.tableView.selectionModel().selectedRows()
for index in sorted(indexes):
self.lblnomSeleccionat.setText(str(index.row()))
def seleccionarCodi(self):
index = self.tableView.selectedIndexes()[0]
id_seleccionat = str(self.tableView.model().data(index))
print ("index : " + str(id_seleccionat))
self.lblnomSeleccionat.setText(str(id_seleccionat))
def actualitzarRecords(self):
index_0 = self.tableView.selectedIndexes()[0]
index_id = str(self.tableView.model().data(index_0))
index_2 = self.tableView.selectedIndexes()[1]
index_probeedor_id = str(self.tableView.model().data(index_2))
index_3 = self.tableView.selectedIndexes()[3]
index_preuTarifa = str(self.tableView.model().data(index_3))
self.model = QSqlQueryModel(self)
self.model.setQuery("UPDATE `ProvaDB`.`preu` SET `preuTarifa`="+index_preuTarifa+" WHERE `id`="+index_id+" and`probeedors_id`="+index_probeedor_id+"")
def cancelRecords(self):
self.model.revertAll()
def insertRecords(self):
self.model.insertRow(self.tableView.currentIndex().row())
def deleteRecords(self):
self.model.removeRow(self.tableView.currentIndex().row())
self.model.submitAll()
def filtrarRecords(self):
self.model.setFilter("preu.id = '"+self.txtEditFiltre.text()+"%'")
if __name__ == '__main__':
app = QApplication(sys.argv)
if not crearConeccio():
sys.exit(1)
formMod = clasArticles()
formMod.show()
sys.exit(app.exec_())

Double buffering in Jython

recently I started learning Jython and now I have rather simply problem. I would like to improve quality of my animation. Unfortunately I don't know how to add double buffering to my applet . Could you help me?
Best regards!
from javax.swing import JToolBar
from javax.swing import JButton
from javax.swing import JFrame
import time
from java import awt
from java.awt import BorderLayout
class Canvas(awt.Canvas):
u"Canvas - drawing area"
def __init__(self,winSize = 400):
self.play = False
self.background=awt.Color.black
self.winSize = winSize
self.l = 0
def playSim(self, play):
if play == True:
self.play = True
self.repaint()
else: self.play = False
def paint(self, g):
g.fillRect(50, int(self.winSize/4), self.l, int(self.winSize/2))
if self.l < self.winSize: self.l += 1
else: self.l = 0
time.sleep(0.02)
if self.play == True: self.repaint()
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
winSize = 600
toolbar = JToolBar()
self.playButton = JButton("Start", actionPerformed=self.playButtonPress )
toolbar.add(self.playButton)
self.add(toolbar, BorderLayout.NORTH)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(winSize, winSize)
self.setResizable(False)
self.setLocationRelativeTo(None)
self.setVisible(True)
self.canvas = Canvas(winSize)
self.getContentPane().add(self.canvas)
self.setTitle("TEST")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
def playButtonPress(self, e):
if self.playButton.getLabel() == "Start":
self.canvas.playSim(True)
self.playButton.setLabel("Stop")
else:
self.playButton.setLabel("Start")
self.canvas.playSim(False)
if __name__ == '__main__':
Example()
I solved my recent problem:
from javax.swing import JToolBar
from javax.swing import JButton
from javax.swing import JFrame
import time
from java import awt
from java.awt import BorderLayout
class Canvas(awt.Canvas):
u"Canvas - drawing area"
def __init__(self,winSize = 400):
self.play = False
self.background=awt.Color.black
self.winSize = winSize
self.l = 0
self.bi = BufferedImage(winSize, winSize, BufferedImage.TYPE_INT_RGB)
self.offScreenGraphics = self.bi.getGraphics()
def playSim(self, play):
if play == True:
self.play = True
self.repaint()
else: self.play = False
def paint(self, g):
self.offScreenGraphics.fillRect(50, int(self.winSize/4), self.l, int(self.winSize/2))
if self.l < self.winSize: self.l += 1
else: self.l = 0
g.drawImage(self.bi, 0, 0, None)
time.sleep(0.02)
if self.play == True: self.repaint()
class Example(JFrame):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
winSize = 600
toolbar = JToolBar()
self.playButton = JButton("Start", actionPerformed=self.playButtonPress )
toolbar.add(self.playButton)
self.add(toolbar, BorderLayout.NORTH)
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setSize(winSize, winSize)
self.setResizable(False)
self.setLocationRelativeTo(None)
self.setVisible(True)
self.canvas = Canvas(winSize)
self.getContentPane().add(self.canvas)
self.setTitle("TEST")
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
def playButtonPress(self, e):
if self.playButton.getLabel() == "Start":
self.canvas.playSim(True)
self.playButton.setLabel("Stop")
else:
self.playButton.setLabel("Start")
self.canvas.playSim(False)
if __name__ == '__main__':
Example()
Now I've another(rather trivial) problem:
How can I make from this python file *the class file* which would be ready to publish it on website as an applet?