This question already has answers here:
Python - Classes and OOP Basics
(6 answers)
What is the difference between objects and classes in Python
(5 answers)
Closed 3 years ago.
I have 2 python files, from one file want to call and run a QDialog with Qlistview. I want to contruct in pythonic way getting value of index just before terminating first python file.
Structure of files:
---Widgetclass.py
---Class_test.py
The code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
lay = QtWidgets.QVBoxLayout(self)
self.button = QtWidgets.QPushButton("Okay")
self.listView = QtWidgets.QListView()
lay.addWidget(self.listView)
self.entry = QtGui.QStandardItemModel()
self.listView.setModel(self.entry)
self.listView.setSpacing(5)
for text in ("One", "two", "Three", "Four",
"Five etc.."):
it = QtGui.QStandardItem(text)
self.entry.appendRow(it)
Code_Group = QtWidgets.QGroupBox(self)
Code_Group.setTitle("&Test")
Code_Group.setLayout(lay)
Vlay = QtWidgets.QVBoxLayout(self)
Vlay.addWidget(Code_Group)
Vlay.addWidget(self.button, alignment=QtCore.Qt.AlignCenter)
Vlay.setSizeConstraint(Vlay.SetFixedSize)
self.listView.selectionModel().currentChanged.connect(self.on_row_changed)
self._INDEX = 0
def on_row_changed(self, current, previous):
self._INDEX = current.row()
print('Row %d selected' % current.row())
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
The constructor:
from Widgetclass import Widget as ls
from PyQt5 import QtCore, QtGui, QtWidgets
def value():
print('Row index:', ls._INDEX, ':') #<---- Value not callable?
ls.close()
subwindow=ls()
subwindow.setWindowModality(QtCore.Qt.ApplicationModal)
subwindow.button.clicked.connect(value)
subwindow.exec_()
Error getting:
AttributeError: type object 'Widget' has no attribute '_INDEX'
I want to achieve value and close the file. but seems not working?!
Related
This question already has answers here:
In PyQt, what is the best way to share data between the main window and a thread
(1 answer)
Background thread with QThread in PyQt
(7 answers)
Example of the right way to use QThread in PyQt?
(3 answers)
Closed 4 months ago.
I'm trying to make Typing speed test app in Pyqt, but it recently started crashing when I was inside QLineEdit. Sometimes it crashed instantly after I tried typing, sometimes only after tens of character were typed.
My code:
from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication, QStackedWidget, QPushButton, QSizePolicy, QLabel, QLineEdit, QHBoxLayout, QVBoxLayout
from PyQt5.QtCore import *
import sys
import time
import random
import threading
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setWindowTitle("Typing Speed Test App")
self.setMinimumSize(1280,720)
global stacked
stacked = QStackedWidget(self)
self.setCentralWidget(stacked)
stacked.addWidget(Menu())
stacked.addWidget(TS_Test())
stacked.addWidget(Statistics())
stacked.setCurrentIndex(1) # test only
class Menu(QWidget):
def __init__(self):
QWidget.__init__(self)
self.frameWidth = self.frameSize().width()
self.frameHeight = self.frameSize().height()
self.initUI()
def initUI(self):
self.button_test = QPushButton(self)
self.button_graph = QPushButton(self)
self.button_test.setFixedWidth(50)
self.button_test.clicked.connect(lambda: stacked.setCurrentIndex(1))
self.button_graph.clicked.connect(lambda: stacked.setCurrentIndex(2))
self.button_graph.clicked.connect(lambda: print(self.frameSize().width()))
self.button_test.move(self.frameSize().width()*50//100-50,200)
self.button_graph.move(200,230)
class TS_Test(QWidget):
def __init__(self):
QWidget.__init__(self)
f = open('paragraphs.txt').read()
self.sentences = f.split('BREAK\n')
self.sentence = random.choice(self.sentences)
self.sentence = self.sentence.strip('\n')
self.word = self.sentence.split()
self.setStyleSheet("QLabel{font-size: 15px;}")
self.initUI()
self.start_thread()
def initUI(self):
self.button_back = QPushButton(self)
self.button_back.clicked.connect(lambda: stacked.setCurrentIndex(0))
self.button_back.move(30,50)
self.lineEdit = QLineEdit()
self.label = QLabel()
self.accuracy_label = QLabel()
self.wpm_label = QLabel()
self.first_letter = self.sentence[0]
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.label)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.accuracy_label)
self.layout.addWidget(self.wpm_label)
self.label.setText(self.sentence)
self.layout.setContentsMargins(250,250,250,300)
self.setLayout(self.layout)
def start_thread(self):
self.t_start=threading.Thread(target=self.start)
self.t_start.start()
def start(self):
while True:
if len(self.lineEdit.text()) > 0:
if self.lineEdit.text()[0] == self.first_letter:
self.time_thread()
break
def time_thread(self):
print('start')
timer_start = time.perf_counter()
self.correct_char = 0
while True:
if (len(self.lineEdit.text()) == len(self.sentence)) and (self.lineEdit.text().split()[-1] == self.word[-1]):
self.written_word = self.lineEdit.text().split(' ')
timer_stop = time.perf_counter()
timer = timer_stop - timer_start
self.wpm = len(self.written_word) / timer * 60
for i in range(len(self.sentence)):
if self.lineEdit.text()[i] == self.sentence[i]:
self.correct_char += 1
self.accuracy = self.correct_char / len(self.sentence) * 100
print(f"Accuracy = {self.correct_char / len(self.sentence) * 100}")
print(f'WPM: {self.wpm:0.3f}')
self.accuracy_label.setText(f'Accuracy = {self.accuracy}%')
self.wpm_label.setText(f'WPM: {self.wpm:0.3f}')
break
class Statistics(QWidget):
def __init__(self):
QWidget.__init__(self)
self.initUI()
def initUI(self):
self.button_back = QPushButton(self)
self.button_back.clicked.connect(lambda: stacked.setCurrentIndex(0))
self.button_back.move(400,300)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainwin = MainWindow()
mainwin.show()
sys.exit(app.exec_())
I've tried doing try and except so that it can print me traceback error, but even that didn't print anything. I read somewhere that it might be because I'm using library threading instead of QThread, but I have no idea if that has something to do with it.
EDIT:
Content in paragraphs.txt:
This line serves as test.
BREAK
Sentence number one.
BREAK
Sentence number two.
BREAK
Line number three.
This question already has answers here:
Connecting slots and signals in PyQt4 in a loop
(3 answers)
Connecting multiples signal/slot in a for loop in pyqt
(3 answers)
Closed 7 months ago.
I came across this issue when making 'QMenu' actions in a loop and assigning a connection with them. Here is an example:
import sys
from PyQt5 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
mbar = self.menuBar()
file_menu = mbar.addMenu("File")
animals = ['Dog','Badger','Bear','Fox']
for animal in animals:
ac = file_menu.addAction(animal)
ac.triggered.connect(lambda: print(animal))
'''Even though each action is assigned a seperate connection with the current animal,
only the last animal is ever printed. Why?'''
def main():
app = QtWidgets.QApplication([sys.argv])
window = MainWindow()
window.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()
The last variable in the loop, 'Fox', is printed for all menu entries. The solution mentioned here is to use the QMenu triggered signal instead, allowing you to store the data in the action and access it that way. Like this:
import sys
from PyQt5 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
mbar = self.menuBar()
file_menu = mbar.addMenu("File")
animals = ['Dog','Badger','Bear','Fox']
for animal in animals:
ac = file_menu.addAction(animal)
ac.setData(animal)
file_menu.triggered.connect(lambda a: print(a.data()))
def main():
app = QtWidgets.QApplication([sys.argv])
window = MainWindow()
window.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()
This works fine but is a little annoying because to work in the real world I would have to implement some sort of check to make sure I was dealing with the right sort of action, for example by making a dataclass to hold the animal and checking for that dataclass instance. But then I discovered that the following approach also works:
import sys
from PyQt5 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
mbar = self.menuBar()
self.file_menu = mbar.addMenu("File")
animals = ['Dog','Badger','Bear','Fox']
for animal in animals:
self.make_menu_entry(animal)
def make_menu_entry(self, animal):
ac = self.file_menu.addAction(animal)
ac.triggered.connect(lambda: print(animal))
def main():
app = QtWidgets.QApplication([sys.argv])
window = MainWindow()
window.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()
So now I'm thinking that this a scope problem, but I don't understand it. Can anyone explain what's happening?
This question already has an answer here:
PyQt4 to PyQt5 how?
(1 answer)
Closed 2 years ago.
Consider a QTableWidget and two buttons "move up" and "move down". Clicking on move up, the current row should move up one row, analogously for "move down".
What's the easiest way to implement the corresponding move up and move down functions? or Is it possible to update this snippet code to pyqt5 which does the same task in pyqt4!
import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
class mtable(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.move_up = QtGui.QAction("Move_Up", self)
self.connect(self.move_up, QtCore.SIGNAL('triggered()'), self.moveUp)
self.move_down = QtGui.QAction("Move_Down",self)
self.connect(self.move_down, QtCore.SIGNAL('triggered()'), self.moveDown)
self.toolbar = self.addToolBar('Toolbar')
self.toolbar.addAction(self.move_up)
self.toolbar.addAction(self.move_down)
##Init Table
self.table = QtGui.QTableWidget(4,3)
for i in range(0,4):
for j in range(0,4):
self.table.setItem(i,j,QtGui.QTableWidgetItem("a_"+str(i)+str(j)))
self.setCentralWidget(self.table)
def moveDown(self):
row = self.table.currentRow()
column = self.table.currentColumn();
if row < self.table.rowCount()-1:
self.table.insertRow(row+2)
for i in range(self.table.columnCount()):
self.table.setItem(row+2,i,self.table.takeItem(row,i))
self.table.setCurrentCell(row+2,column)
self.table.removeRow(row)
def moveUp(self):
row = self.table.currentRow()
column = self.table.currentColumn();
if row > 0:
self.table.insertRow(row-1)
for i in range(self.table.columnCount()):
self.table.setItem(row-1,i,self.table.takeItem(row+1,i))
self.table.setCurrentCell(row-1,column)
self.table.removeRow(row+1)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
tb = mtable()
tb.show()
sys.exit(app.exec_())
All you have to do to convert to PyQt5 is change the imports and modules from QtGui to QtWidgets and the syntax for the signal-slot connection.
import sys
from PyQt5 import QtWidgets
class mtable(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.move_up = QtWidgets.QAction("Move_Up", self)
self.move_up.triggered.connect(self.moveUp)
self.move_down = QtWidgets.QAction("Move_Down",self)
self.move_down.triggered.connect(self.moveDown)
self.toolbar = self.addToolBar('Toolbar')
self.toolbar.addAction(self.move_up)
self.toolbar.addAction(self.move_down)
##Init Table
self.table = QtWidgets.QTableWidget(4,3)
for i in range(0,4):
for j in range(0,4):
self.table.setItem(i,j,QtWidgets.QTableWidgetItem("a_"+str(i)+str(j)))
self.setCentralWidget(self.table)
The rest of the class should be the same, just one more edit for QApplication.
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
tb = mtable()
tb.show()
sys.exit(app.exec_())
This question already has an answer here:
How to fix error in my pyqt programm (first argument of unbound method must have type 'QDialog') ?
(1 answer)
Closed 3 years ago.
I'm trying to build a GUI app using PyQt5 and Python 3.7 and I've decided to break the code in different modules. When i try to import a function that creates an instance of a custom widget, an error related to 'sis'. What I read is that 'sis' is a way of encapsulation C/C++ code to be run in python. But how can I work with that?
This is the code that runs the app:
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setGeometry(10,35,1500,800)
self.setWindowTitle("Cotizador TuCheff")
#self.setWindowIcon(QtGui.QIcon(''))
mainWindow(self)
def mainWindow(self):
from PyQt5 import QtCore, QtGui, QtWidgets
from Pages.Quote import quote
barMenu = QtWidgets.QTabWidget(self)
tab1 = QtWidgets.QWidget()
quoteLayout = QtWidgets.QVBoxLayout()
quoteGenerator = quote.makeQuoteWindow()
quoteLayout.addWidget(quoteGenerator)
tab1.setLayout(quoteLayout)
barMenu.addTab(tab1, "&Nueva CotizaciĆ³n")
self.setCentralWidget(barMenu)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
And file, where I try to get a custom widget, is:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication
import sys
def makeQuoteWindow():
quoteWindow = QuoteWindow
quoteWindow.create()
#app = QApplication([])
#window = quoteWindow()
#window.show()
#status = app.exec_()
#sys.exit(status)
class QuoteWindow(QtWidgets.QWidget):
def __init__(self):
super(QuoteWindow, self).__init__()
def create(self):
mainWidget = QtWidgets.QWidget()
vLayout1 = QtWidgets.QVBoxLayout()
#=======------------------------ UPPER SIDE -------------------
hLayout1 = QtWidgets.QHBoxLayout()
##A LOT OF WIDGETS AND LAYOUTS
hLayout2 = QtWidgets.QHBoxLayout()
#display content
vLayout1.addLayout(hLayout1)
vLayout1.addLayout(hLayout2)
hLayout2.addItem(vSpacer1)
mainWidget.setLayout(vLayout1)
return mainWidget
if __name__ == "__main__":
makeQuoteWindow()
The error is:
TypeError: create(self, window: sip.voidptr = 0, initializeWindow: bool = True, destroyOldWindow: bool = True): first argument of unbound method must have type 'QWidget'
Try it:
main.py
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import QApplication, QMainWindow
# from Pages.Quote import quote
from Quote import QuoteWindow
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setGeometry(10,35,1500,800)
self.setWindowTitle("Cotizador TuCheff")
self.setWindowIcon(QtGui.QIcon('im.png'))
# mainWindow(self)
self.mainWindow()
def mainWindow(self):
# from Pages.Quote import quote
self.quoteWindow = QuoteWindow() # +++
barMenu = QtWidgets.QTabWidget(self)
tab1 = QtWidgets.QWidget()
quoteLayout = QtWidgets.QVBoxLayout()
# quoteGenerator = quote.makeQuoteWindow()
# quoteLayout.addWidget(quoteGenerator)
quoteLayout.addWidget(self.quoteWindow) # +++
tab1.setLayout(quoteLayout)
barMenu.addTab(tab1, "&Nueva CotizaciĆ³n")
self.setCentralWidget(barMenu)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
Quote.py
from PyQt5 import QtCore, QtWidgets, QtGui
class QuoteWindow(QtWidgets.QWidget):
def __init__(self):
super(QuoteWindow, self).__init__()
def create(self):
mainWidget = QtWidgets.QWidget()
vLayout1 = QtWidgets.QVBoxLayout()
#=======------------------------ UPPER SIDE -------------------
hLayout1 = QtWidgets.QHBoxLayout()
##A LOT OF WIDGETS AND LAYOUTS
hLayout2 = QtWidgets.QHBoxLayout()
#display content
vLayout1.addLayout(hLayout1)
vLayout1.addLayout(hLayout2)
hLayout2.addItem(vSpacer1)
mainWidget.setLayout(vLayout1)
return mainWidget
This question already has answers here:
Aligning text in QTextEdit?
(2 answers)
Closed 4 years ago.
I am doing some random choice picker where there's a place to display info user keyed in. (which I used text browser), How do I set the text to be always align center?
self.textBrowser.setText(newList + "\n\nanalyzing in ...")
QtTest.QTest.qWait(1000)
self.textBrowser.setText(newList + "\n\nanalyzing in ..." + "\n\n 3")
QTextBrowser Class Inherits: QTextEdit
QTextEdit::setAlignment(Qt::Alignment)
Sets the alignment of the current paragraph to a. Valid alignments are Qt::AlignLeft, Qt::AlignRight, Qt::AlignJustify and Qt::AlignCenter (which centers horizontally).
Sorry, I have PyQt5:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Win(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.i = 5
self.textBrowser = QtWidgets.QTextBrowser()
self.textBrowser.setAlignment(QtCore.Qt.AlignCenter) # <-------------
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.textBrowser)
self.setLayout(layout)
timer = QtCore.QTimer(self, interval=1000, timeout=self.print_out)
timer.start()
def print_out(self, string="Hello world!"):
self.textBrowser.append(string + "\n\nanalyzing in ...\n {}".format('----' * self.i))
self.i += 1
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
myWin = Win()
myWin.show()
sys.exit(app.exec_())