I want when I click on select botton in QTableWidget(tblbimar) give me the same number of rows(QTable).
But when I click on "select" button nothing happen!
Of course I tried whether the signal "tbl_bimar_row" is sent or not؟(it work correctly)
# -*- coding: utf-8 -*-
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import os
import sys
class groupbutton(QWidget):
tbl_bimar_row = pyqtSignal(int)
def __init__(self,parent=None):
super(groupbutton,self).__init__(parent)
self.parent = parent
btnselect = QPushButton("select")
layout = QHBoxLayout()
layout.setContentsMargins(0,0,0,0)
layout.setSpacing(5)
layout.addWidget(btnselect)
self.setLayout(layout)
self.connect(btnselect,SIGNAL("clicked()"),self.return_row)
def return_row(self):
widget_pos = QtGui.qApp.focusWidget()
index = self.parent.indexAt(widget_pos.parentWidget().pos())
# OR index = self.parent.indexAt(widget_pos.pos())
if index.isValid():
self.tbl_bimar_row.emit(index.row())
class Jarahi_add(QDialog,Ui_My_Form):
def __init__(self,parent=None):
super(Jarahi_add,self).__init__(parent)
self.setupUi(self)
self.bimar_id = None
get_bimar()
self.connect(self.txtbimarname,SIGNAL("textChanged(QString)"),self.get_bimar)
def bimar_select(self,row):
print(self.tblbimar.item(row,1).text())
def get_bimar(self):
data = [['1','2','3','4','5'],['6','7','8','9','10']]
for row in data:
inx = data.index(row)
self.tblbimar.insertRow(inx)
self.tblbimar.setItem(inx,0,QTableWidgetItem(row[0]))
self.tblbimar.setItem(inx,1,QTableWidgetItem(row[1]))
self.tblbimar.setItem(inx,2,QTableWidgetItem(row[2]))
self.tblbimar.setItem(inx,3,QTableWidgetItem(row[3]))
self.tblbimar.setItem(inx,4,QTableWidgetItem(row[4]))
selbtn = groupbutton(parent=self.tblbimar)
selbtn.tbl_bimar_row.connect(self.bimar_select)
self.tblbimar.setCellWidget(inx,5,selbtn)
# self.tblbimar.setItem(inx,5,QTableWidgetItem(smart_text(row[0])))
self.tblbimar.resizeColumnsToContents()
self.tblbimar.resizeRowsToContents()
thank you
I changed the above code as the following and it worked:
class groupbutton(QWidget):
tbl_bimar_row = pyqtSignal(int)
def __init__(self,parent=None,app=None):
super(tblbutton,self).__init__(parent)
self.parent = parent
self.app = app
...
...
def return_row(self):
widget_pos = self.app.focusWidget()
index = self.parent.indexAt(widget_pos.parentWidget().pos())
self.tbl_bimar_row.emit(index.row())
class Jarahi_add(QDialog,Ui_My_Form):
...
...
def get_bimar(self):
if data:
for row in data:
...
...
selbtn = tblbutton(parent=self.tblbimar,app=self)
selbtn.tbl_bimar_row.connect(self.bimar_select)
self.tblbimar.setCellWidget(inx,5,selbtn)
Related
This is the code.
I am using pyCharm and python 3.7
I am able to get the GUI with all the buttons but when i click on the button it won't show in the display box until I click on the display box that is if i click on "5" it won't show in the display box until i click on the display box.
I am using MacOsCatalina.
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QPushButton
from functools import partial
__version__ = "0.1"
ERROR_MSG = "ERROR"
>The Main GUI class
class calcgui(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("calc")
self.setFixedSize(300,300)
self.generalLayout = QVBoxLayout()
self._centralWidget = QWidget(self)
self.setCentralWidget(self._centralWidget)
self._centralWidget.setLayout(self.generalLayout)
self._createDisplay()
self._createButtons()
def _createDisplay(self):
self.display = QLineEdit()
self.display.setFixedHeight(50)
self.display.setAlignment(Qt.AlignRight)
self.display.setReadOnly(True)
self.generalLayout.addWidget(self.display)
def _createButtons(self):
self.buttons = {}
buttonsLayout = QGridLayout()
buttons = {"7":(0,0),
"8":(0,1),
"9":(0,2),
"C":(0,3),
"/":(0,4),
"4":(1,0),
"5":(1,1),
"6":(1,2),
"*":(1,3),
"(":(1,4),
"1":(2,0),
"2":(2,1),
"3":(2,2),
"-":(2,3),
")":(2,4),
"0":(3,0),
"00":(3,1),
".":(3,2),
"+":(3,3),
"=":(3,4)
}
for btnText, pos in buttons.items():
self.buttons[btnText] = QPushButton(btnText)
self.buttons[btnText].setFixedSize(50,50)
buttonsLayout.addWidget(self.buttons[btnText],pos[0],pos[1])
self.generalLayout.addLayout(buttonsLayout)
def setDisplayText(self, text):
self.display.setText(text)
self.display.setFocus()
def DisplayText(self):
return self.display.text()
def clearDisplay(self):
self.setDisplayText("")
>This is the linking class
class pycalcu:
def __init__(self,model,view):
self._evaluate = model
self._view = view
self._connectSignals()
def _calculateResult(self):
result = self._evaluate(expression=self._view.DisplayText())
self._view.setDisplayText(result)
def _buildExpression(self,sub_exp):
if self._view.DisplayText() == ERROR_MSG:
self._view.clearDisplay()
expression = self._view.DisplayText() + sub_exp
self._view.setDisplayText(expression)
def _connectSignals(self):
for btnText, btn in self._view.buttons.items():
if btnText not in {"C","="}:
btn.clicked.connect(partial(self._buildExpression,btnText))
self._view.buttons["="].clicked.connect(self._calculateResult)
return self._view.display.returnPressed.connect(self._calculateResult)
self._view.buttons["C"].clicked.connect(self._view.clearDisplay)
def evaluateExpression(expression):
try:
result = str(eval(expression, {}, {}))
except Exception:
result = ERROR_MSG
return result
def main():
pycalc = QApplication(sys.argv)
view = calcgui()
view.show()
model = evaluateExpression
pycalcu(model=model,view=view)
sys.exit(pycalc.exec_())
if __name__ == "__main__":
main()
Sorry, I didn’t really delve into your program logic.
I noted the changes that I made.
Give it a try.
import sys
from PyQt5.QtWidgets import (QApplication, QLabel, QWidget, QMainWindow,
QGridLayout, QVBoxLayout, QLineEdit, QPushButton)
from PyQt5.QtCore import Qt
from functools import partial
__version__ = "0.1"
ERROR_MSG = "ERROR"
# >The Main GUI class
class calcgui(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("calc")
self.setFixedSize(300,300)
self._centralWidget = QWidget(self)
self.setCentralWidget(self._centralWidget)
self.generalLayout = QVBoxLayout(self._centralWidget)
self._createDisplay()
self._createButtons()
def _createDisplay(self):
self.display = QLineEdit()
self.display.setFixedHeight(50)
self.display.setAlignment(Qt.AlignRight)
self.display.setReadOnly(True)
self.generalLayout.addWidget(self.display)
def _createButtons(self):
self.buttons = {}
buttonsLayout = QGridLayout()
buttons = {
"7":(0,0),
"8":(0,1),
"9":(0,2),
"C":(0,3),
"/":(0,4),
"4":(1,0),
"5":(1,1),
"6":(1,2),
"*":(1,3),
"(":(1,4),
"1":(2,0),
"2":(2,1),
"3":(2,2),
"-":(2,3),
")":(2,4),
"0":(3,0),
"00":(3,1),
".":(3,2),
"+":(3,3),
"=":(3,4)
}
for btnText, pos in buttons.items():
self.buttons[btnText] = QPushButton(btnText)
self.buttons[btnText].setFixedSize(50,50)
buttonsLayout.addWidget(self.buttons[btnText],pos[0],pos[1])
# <----
self.generalLayout.addLayout(buttonsLayout) # <----
def setDisplayText(self, text):
self.display.setText(text)
self.display.setFocus()
def DisplayText(self):
return self.display.text()
def clearDisplay(self):
self.setDisplayText("")
# >This is the linking class
class pycalcu:
def __init__(self,model, view):
self._evaluate = model
self._view = view
self._connectSignals()
def _calculateResult(self):
result = self._evaluate(expression=self._view.DisplayText())
self._view.setDisplayText(result)
def _buildExpression(self, sub_exp):
if self._view.DisplayText() == ERROR_MSG:
self._view.clearDisplay()
expression = self._view.DisplayText() + sub_exp
self._view.setDisplayText(expression)
def _connectSignals(self):
for btnText, btn in self._view.buttons.items():
if btnText not in {"C", "="}:
btn.clicked.connect(partial(self._buildExpression, btnText))
self._view.buttons["="].clicked.connect(self._calculateResult)
self._view.buttons["C"].clicked.connect(self._view.clearDisplay) # +++
return self._view.display.returnPressed.connect(self._calculateResult)
# ? self._view.buttons["C"].clicked.connect(self._view.clearDisplay) # ---
def evaluateExpression(expression):
try:
result = str(eval(expression, {}, {}))
except Exception:
result = ERROR_MSG
return result
def main():
pycalc = QApplication(sys.argv)
view = calcgui()
view.show()
model = evaluateExpression
pycalcu(model=model, view=view)
sys.exit(pycalc.exec_())
if __name__ == "__main__":
main()
import sys
from PyQt4 import QtCore, QtGui, uic
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import time
import datetime
import re
import random
import csv
from CropClass import *
from Wheat_class import *
from Potato_class import *
win1 = uic.loadUiType("MenuScreen.ui")[0]
win2 = uic.loadUiType("WheatScreen.ui")[0]
win3 = uic.loadUiType("PotatoScreen.ui") [0]
class MenuScreen(QtGui.QMainWindow, win1):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.BtnCreateSimulation.clicked.connect(self.changeSimulation)
def changeSimulation(self):
if self.RdoWheat.isChecked() ==True:
print("Wheat is picked")
new_crop=Wheat()
self.wheatSimulation()
elif self.RdoPotato.isChecked() == True:
print("Potato is picked")
new_crop = Potato()
self.PotatoSimulation()
def wheatSimulation(self):
print("Hello")
self.hide()
WheatWindow.show()
def PotatoSimulation(self):
self.hide()
PotatoWindow.show()
class PotatoScreen(QtGui.QMainWindow, win3):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.BtnBacktoMenu.clicked.connect(self.BackToMain)
def BackToMain(self):
self.hide()
MenuWindow.show()
class WheatScreen(QtGui.QMainWindow, win2):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.setupUi(self)
new_crop = Wheat()
self.BtnBacktoMenu.clicked.connect(self.BackToMain)
self.BtnManual.clicked.connect(self.ManualCalculate)
def BackToMain(self):
self.hide()
MenuWindow.show()
def ManualCalculate(self):
water = self.spBoxWater.value()
light= self.spBoxLight.value()
print("water", water, "light", light)
def main():
app = QtGui.QApplication(sys.argv)
WheatWindow = WheatScreen(None)
PotatoWindow = PotatoScreen(None)
MenuWindow = MenuScreen(None)
MenuWindow.show()
app.exec_()
if __name__ == "__main__":
main()
I have created a program in Python which simulates the growth rates of crops. The user is able to chose between the crop is wheat or potatoes I am trying to create a GUI using PYQT. The problem I am having is that when I try and load the program the program is not recognizing the other screen layouts. The main function should be setting up the screen layouts
I have a class GUI, where I set up all my widgets etc. for my GUI. I use threading to start a process from another class. This works fine, as long that other process just runs through. In some cases, I need to wait for a user input to proceed. I used tkmessagebox for this, but the messagebox doesn't appear and blocks the GUI without any error message. (It works when not started through the GUI).
Here's part of my code:
GUI part
from Tkinter import *
import Tkinter as ttk
import ttk
from tkMessageBox import *
from GUI_reader import Commandline_Reader
import threading
import Queue
class GUI:
def __init__(self,master):
self.master = master
self.argString='ds'
## self.workerThread()
button = ttk.Button(text='start', command=self.go).grid()
...
def go(self):
self.thread = threading.Thread(target=self.workerThread)
self.thread.daemon = True
self.thread.start()
...
def workerThread(self):
...
reader = Commandline_Reader(master, self.argString)
if reader.connect():
print 'success'
reader.run()
print 'success'
if __name__ == '__main__':
root = Tk()
client = GUI(root)
root.mainloop()
class commandline_reader:
import tkMessageBox
...
class Commandline_Reader:
def __init__(self, master, argString='')
self.master = master
...
def connect(self)
...
def run(self):
...
tkMessageBox.askokcancel('Calibration', 'Hit ok to start calibration', parent= self.master)
...
if __name__ == '__main__':
reader = Commandline_Reader(self,master)
if not reader.connect():
exit(-1)
if not reader.run():
exit(-2)
I am new to both pyqt and python so I'm sure that my question would seem stupid, so thank you for reading and answer it. It is really helpful.
Here is my source code
# -*- coding: utf-8 -*-
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8"))
class Prog(QDialog):
def __init__(self,parent=None):
super(Prog,self).__init__(parent)
self.start_P()
def start_P(self):
progressDialog=QProgressDialog(self)
progressDialog.setWindowModality(Qt.WindowModal)
progressDialog.setMinimumDuration(5)
progressDialog.setWindowTitle(self.tr("请等待"))
progressDialog.setLabelText(self.tr("拷贝..."))
progressDialog.setCancelButtonText(self.tr("取消"))
progressDialog.setRange(0,100)
progressDialog.setAutoClose(True)
for i in range(101):
progressDialog.setValue(i)
QThread.msleep(10)
if progressDialog.wasCanceled():
return
self.connect(progressDialog,SIGNAL("closed()"))
def main():
app = QApplication(sys.argv)
pp = Prog()
pp.show()
app.exec_()
if __name__ == '__main__':
main()
There are some Chinese characters, but it's irrelevant. The strange part is when I execute this program I would get a window of progress dialog, that is what I want. But when it is auto closed a pythonw window generated automatically.
I was curious about why this pythonw window was generated and want to know how to avoid it.
That's because you are creating your QProgressDialog as child of a QDialog, checkout the line that says progressDialog=QProgressDialog(self). Checkout how this example works:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#---------
# IMPORT
#---------
from PyQt4 import QtGui, QtCore
#---------
# MAIN
#---------
class MyThread(QtCore.QThread):
progress = QtCore.pyqtSignal(int)
_stopped = False
def __init__(self, parent=None):
super(MyThread, self).__init__(parent)
def stop(self):
self._stopped = True
def start(self):
self._stopped = False
super(MyThread, self).start()
def run(self):
for progressNumber in range(101):
self.progress.emit(progressNumber)
self.msleep(22)
if self._stopped:
return
class MyWindow(QtGui.QProgressDialog):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.threadProgress = MyThread(self)
self.threadProgress.progress.connect(self.setValue)
def stop(self):
self.threadProgress.stop()
def start(self):
self.threadProgress.start()
def hideEvent(self, event):
self.close()
if __name__ == "__main__":
import sys
codec = QtCore.QTextCodec.codecForName("utf8")
QtCore.QTextCodec.setCodecForTr(codec)
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.setWindowTitle(main.tr("请等待"))
main.setLabelText(main.tr("拷贝..."))
main.setCancelButtonText(main.tr("取消"))
main.setRange(0,100)
main.canceled.connect(main.stop)
main.show()
main.start()
sys.exit(app.exec_())
I need help inserting a button inside in a QLineEdit that can call a function.
For example, like this google image:
Below is a nearly direct translation of the Qt code from here.
Differences:
button is always visible
clicking on the button emits buttonClicked(bool) signal
Code:
from PyQt4 import QtGui, QtCore
class ButtonLineEdit(QtGui.QLineEdit):
buttonClicked = QtCore.pyqtSignal(bool)
def __init__(self, icon_file, parent=None):
super(ButtonLineEdit, self).__init__(parent)
self.button = QtGui.QToolButton(self)
self.button.setIcon(QtGui.QIcon(icon_file))
self.button.setStyleSheet('border: 0px; padding: 0px;')
self.button.setCursor(QtCore.Qt.ArrowCursor)
self.button.clicked.connect(self.buttonClicked.emit)
frameWidth = self.style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth)
buttonSize = self.button.sizeHint()
self.setStyleSheet('QLineEdit {padding-right: %dpx; }' % (buttonSize.width() + frameWidth + 1))
self.setMinimumSize(max(self.minimumSizeHint().width(), buttonSize.width() + frameWidth*2 + 2),
max(self.minimumSizeHint().height(), buttonSize.height() + frameWidth*2 + 2))
def resizeEvent(self, event):
buttonSize = self.button.sizeHint()
frameWidth = self.style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth)
self.button.move(self.rect().right() - frameWidth - buttonSize.width(),
(self.rect().bottom() - buttonSize.height() + 1)/2)
super(ButtonLineEdit, self).resizeEvent(event)
Usage:
import sys
from PyQt4 import QtGui
def buttonClicked():
print 'You clicked the button!'
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = ButtonLineEdit('/path/to/my_fancy_icon.png')
main.buttonClicked.connect(buttonClicked)
main.show()
sys.exit(app.exec_())
Here is the runnable code:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from sys import argv, exit
class ButtonInLineEdit(QLineEdit):
def __init__(self,parent=None):
QLineEdit.__init__(self,parent)
self.ButtonShowKeyboard = QToolButton(self)
self.ButtonShowKeyboard.setCursor(Qt.PointingHandCursor)
self.ButtonShowKeyboard.setFocusPolicy(Qt.NoFocus)
self.ButtonShowKeyboard.setIcon(QIcon("icons/myIcon.png"))
self.ButtonShowKeyboard.setStyleSheet("background: transparent; border: none;")
layout = QHBoxLayout(self)
layout.addWidget(self.ButtonShowKeyboard,0,Qt.AlignRight)
layout.setSpacing(0)
layout.setMargin(5)
self.ButtonShowKeyboard.setToolTip(QApplication.translate("None", "Show virtual keyboard", None, QApplication.UnicodeUTF8))
def MyFunction(arg=None):
print "MyFunction() called: arg = %s"%arg
a=QApplication(argv)
LineEdit = ButtonInLineEdit()
LineEdit.connect(LineEdit.ButtonShowKeyboard, SIGNAL("clicked()"), MyFunction)
LineEdit.show()
exit(a.exec_())
As of Qt 5.2 there is QLineEdit.addAction() which is a built-in way to do that.
Also QLineEdit.setClearButtonEnabled() adds a cross button to the right (as on certain OSX controls) to clear the widget's contents.
Thanks to our colleague, Avaris, But his example is did not convince me and I decided to make a on another more easier to and less code.
Go to learn!
#this code for example in btninlineedit.py
from PyQt4.QtGui import *
from PyQt4.QtCore import Qt
from PyQt4 import QtCore, QtGui
#Andrey Zhuk.
#####
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class ButtonInLineEdit(QLineEdit):
def __init__(self,parent=None):
QLineEdit.__init__(self,parent)
self.ButtonShowKeyboard = QToolButton(self)
self.ButtonShowKeyboard.setCursor(Qt.PointingHandCursor)
#self.ButtonShowKeyboard.show()
self.ButtonShowKeyboard.setFocusPolicy(Qt.NoFocus)
self.ButtonShowKeyboard.setIcon(QtGui.QIcon("images/YourIcon.svg"))
self.ButtonShowKeyboard.setStyleSheet("background: transparent; border: none;")
layout = QHBoxLayout(self)
layout.addWidget(self.ButtonShowKeyboard,0,Qt.AlignRight)
layout.setSpacing(0)
layout.setMargin(5)
# ToolTip
self.ButtonShowKeyboard.setToolTip(QtGui.QApplication.translate("None", "Show virtual keyboard", None, QtGui.QApplication.UnicodeUTF8))
#this code for example in main.py
class main(/////****///**/):
def __init__(self):
#blablablablaaaa
self.KeyboardShow = False
self.connect(self.LineEdit.ButtonShowKeyboard, QtCore.SIGNAL("clicked()"), self.KeyboardShowHide)
def KeyboardShowHide(self):
try:
if self.KeyboardShow:
self.KeyboardShow = False
self.WidgetKeyboard.hide()
else:
self.KeyboardShow = True
self.WidgetKeyboard.show()
except:
debug ("ошибка при вызове функции скрытые или показа клавиатуры (Main Window)")
#this code for example in btninlineedit.py
from forms.btninlineedit import ButtonInLineEdit
self.LineEdit = ButtonInLineEdit()
In qt C++, I can drag and drop pushButton in the left of LineEdit. After that, I just need to set styleSheet for LineEdit with this code:
int FramWidth = lineEdit->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
lineEdit->setStyleSheet(QString("QLineEdit{padding-right: %1px; }").arg(ui->pushButton->sizeHint().width() + FramWidth +5));
And it works for me. Hope it can help.
class LineEditFileDialogWidget(QtWidgets.QLineEdit):
def __init__(self, parent=None):
super(LineEditFileDialogWidget, self).__init__(parent)
self.setReadOnly(True)
icon = QtWidgets.QApplication.style().standardIcon(QtWidgets.QStyle.SP_DirIcon)
self.action = self.addAction(icon, QtWidgets.QLineEdit.TrailingPosition)
self.action.triggered.connect(some function)
Here is an example of using the icon along with QLineEdit