I work in GPG key generation programm with Python-GnuGP lib (just to make my life easier). I have used PyQt for the UI and to get values as well as two classes (one for the main up and the other for the dialog) to gen my key. The problem is that when I execute the GenButton I get the following errors in terminal:
Key-Type: RSA
Key-Length: 4096
Passphrase: 1202
Name-Real: TestUser
Name-Email: test#gmail.com
Expire-Date: 2019-3-3
%commit
key not created
Here is my code: I tested it with build in values and all worked fine, but when I pass values from the QlineEdit boxes I get the above error.
class GenKeyDialog(QtGui.QDialog, Ui_GPGGenerateWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setupUi(self)
self.gpg = gnupg.GPG(homedir='keys')
self.gpg.encoding = 'utf-8'
self.GenButton.clicked.connect(self.genkey)
def genkey(self):
type = "RSA"
length = 4096
name = str(self.NameEdit.text())
email = str(self.EmailEdit.text())
if str(self.PassEdit.text()) == str(self.RPassEdit.text()):
passs = str(self.PassEdit.text())
else:
print "passwords do not match"
return
expire = str(self.ExpireEdit.text())
input_data = self.gpg.gen_key_input(key_type=type, key_length=length, name_real=name, name_email=email, passphrase=passs, expire_date=expire)
print input_data
key = self.gpg.gen_key(input_data)
print key
class Main_window_ex(QMainWindow, Ui_MainWindow):
def createPGP(self):
dialog = GenKeyDialog()
ret = dialog.exec_()
def __init__(self, parent = None):
"""
Default Constructor. It can receive a top window as parent.
"""
Screenshot:
You are implementing Main_window_ex.__init__ as an empty function. When instances of that class are initialised, nothing will happen.
I suspect that what you want is to have the Main_window_ex instances initialise exactly like its parent class. If that's what you want, don't implement a specific Main_window_ex.__init__.
You would have learned this when you worked through the Python tutorial, specifically its chapter on classes and inheritance. Hopefully this is a reminder :-)
Related
Is there any way to instantiate a subclass object as an extension of a superclass object, in such a way that the subclass retains the arguments passed to the superclass?
I'm working on a simple melody generator to get back into programming. The idea was that a Project can contain an arbitrary number of Instruments, which can have any number of Sequences.
Every subordinate object would retain all of the information of the superior objects (e.g. every instrument shares the project's port device, and so forth).
I figured I could do something like this:
import rtmidi
class Project:
def __init__(self, p_port=None):
self.port = p_port
# Getter / Setter removed for brevity
class Instrument(Project):
def __init__(self, p_channel=1)
self.channel = p_channel
# Getter / Setter removed for brevity
def port_setup():
midi_out = rtmidi.MidiOut()
selected_port = midi_out.open_port(2)
return selected_port
if __name__ == '__main__':
port = port_setup()
project = Project(p_port=port)
project.inst1 = Instrument()
print(project.port, project.inst1.port)
The expectation was that the new instrument would extend the created Project and inherit the port passed to its parent.
However, that doesn't work; the project and instrument return different objects, so there seems to be no relation between the objects at all. A quick Google search also doesn't turn up any information, which I assume means I'm really missing something.
Is there a proper way to set up nested structures like this?
Your relationship is that each Project has many Instruments. An Instrument is not a Project.
One first step could be to tell each Instrument which project is belongs to:
import rtmidi
class Project:
def __init__(self, p_port=None):
self.port = p_port
# Getter / Setter removed for brevity
class Instrument:
def __init__(self, project, p_channel=1)
self.project = project
self.channel = p_channel
# Getter / Setter removed for brevity
def port_setup():
midi_out = rtmidi.MidiOut()
selected_port = midi_out.open_port(2)
return selected_port
if __name__ == '__main__':
port = port_setup()
project = Project(p_port=port)
project.inst1 = Instrument(project)
print(project.port, project.inst1.project.port)
I try to use QRemoteObjects to share more than two objects but
i got "Dynamic metaobject is not assigned" warning while run client.py example, and i can't find out what happened, my example work fine, can anyone give me some advices?
server.py
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtRemoteObjects import *
from faker import Faker
fake = Faker()
class Name(QObject):
sig_name = pyqtSignal(str)
def __init__(self):
super().__init__()
self.name = ''
self.startTimer(1000)
def timerEvent(self, event):
self.name = fake.name()
self.sig_name.emit(self.name)
class Email(QObject):
sig_email = pyqtSignal(str)
def __init__(self):
super().__init__()
self.startTimer(1000)
def timerEvent(self, event):
self.sig_email.emit(fake.email())
class Server(QObject):
def __init__(self):
super().__init__()
self.name = Name()
self.email = Email()
host = QRemoteObjectHost(QUrl('local:server'), self)
r1 = host.enableRemoting(self.name, 'name')
r2 = host.enableRemoting(self.email, 'email')
print([r1, r2])
def print_name(self, x):
print(x)
app = QCoreApplication([])
s = Server()
app.exec()
client.py
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtRemoteObjects import *
class Client(QObject):
def __init__(self):
super().__init__()
node = QRemoteObjectNode(self)
node.connectToNode(QUrl("local:server"))
self.remote_name = node.acquireDynamic('name')
self.remote_email = node.acquireDynamic('email')
self.remote_name.initialized.connect(self.onInitName)
self.remote_email.initialized.connect(self.onInitEmail)
def onInitName(self):
self.remote_name.sig_name.connect(self.print_info)
def onInitEmail(self):
self.remote_email.sig_email.connect(self.print_info)
def print_info(self, x):
print('-->:', x)
app = QCoreApplication([])
c = Client()
app.exec()
After i run python server.py in terminal one and run python client.py in terminal two.
I got some warning as below in terminal two.
In C++ you can purchase the replica using 2 methods:
QRemoteObjectNode::acquire():
SimpleSwitchReplica *rep = repNode.acquire<SimpleSwitchReplica>("SimpleSwitch"));
QRemoteObjectNode::acquireDynamic():
QRemoteObjectDynamicReplica *rep = repNode.acquireDynamic("SimpleSwitch");
As the second method is observed, a QRemoteObjectDynamicReplica is used which is an object that is class created on-the-fly by copying the properties, signals and slots but does not contain all the information of the node class so it is not an exact copy so which has disadvantages as the docs points out:
There are generated replicas (replicas having the header files
produced by the Replica Compiler), and dynamic replicas, which are
generated on-the-fly. This is the class for the dynamic type of
replica.
When the connection to the Source object is made, the initialization
step passes the current property values (see Replica Initialization).
In a DynamicReplica, the property/signal/slot details are also sent,
allowing the replica object to be created on-the-fly. This can be
conventient in QML or scripting, but has two primary disadvantages.
First, the object is in effect "empty" until it is successfully
initialized by the Source. Second, in C++, calls must be made using
QMetaObject::invokeMethod(), as the moc generated lookup will not be
available.
(emphasis mine)
And in the case of PyQt, it only supports the second method, so you get that warning message indicating possible problems.
I have a GUI, and through it I load some data. When a file is loaded, its filename is used as an identifier, which populates the GUI and also a dictionary underneath, to keep track of the current state for each file.
However, with this approach I can't get any autocomplete from the MetaData class, e.g. when I want to access data.container.[GUIcurrentFile].one_of_many_attributes.
Is there a way around this? Perhaps keeping files in memory in an entirely different fashion? What do people normally do in this scenarios? I'm not too familiar with GUI development.
class Data:
def __init__(self):
self.container = dict()
def load(self, name):
self.container[name] = MetaData()
class MetaData:
def __init__(self):
self.one_of_many_attributes = None
# This is instantiated in the main part of the GUI, e.g. self.data = Data()
data = Data()
## Series of events happening through the GUI
# Grab loaded file through a GUI
GUIcurrentFile = "file1"
data.load(GUIcurrentFile)
GUIcurrentFile = "file2"
data.load(GUIcurrentFile)
# Each file has separate attributes
data.container[GUIcurrentFile].one_of_many_attributes = "foo"
# File is removed from GUI, and can easily be removed from dictionary internally
data.container.pop(GUIcurrentFile)
Okay, so type hinting finally clicked for me. I hope the original title makes sense, in relation to this answer. Else, feel free to edit it.
Defining MetaData first, it's very straight forward to add type hinting for PyCharm, if a method is implemented to return an object of type "MetaData".
class MetaData:
def __init__(self):
self.foo = None
self.really_long_name = None
class Data:
def __init__(self):
self.container = dict()
def load(self, name):
self.container[name] = MetaData()
def get(self, name) -> MetaData: # specify what dict lookup returns
return self.container[name]
data = Data()
data.load("file1")
data.get("file1").foo
I am facing weird error when I try to access self.cursor_dat' from class in different script. It says:ImportError: cannot import name query_selection_class`. The error also occur without trying to access the variable. There is just something wrong with the import command.
here is the file1.py where I create the variable:
class connection_settings_class(QtGui.QMainWindow,Ui_main_connection_settings_window):
def __init__(self):
self.create_connection_window()
self.host = 'localhost'
self.port = '3307'
self.user = 'root'
self.password = ''
self.database = 'rtr'
def connection(self):
""" connect to the database and create cursor that will be used to exetute MySQL queries """
try:
self.cnxn = pyodbc.connect(driver = '{MySQL ODBC 5.3 ANSI Driver}', # ANSI or Unicode
host = self.host,
port = self.port,
user = self.user,
password = self.password,
database = self.database)
except:
print('Connection FAIL')
**self.cursor_dat** = self.cnxn.cursor()
**self.cursor_dat**.execute("""SELECT * FROM test_db.attempt;""")
row = **self.cursor_dat**.fetchone()
if row:
print("Succesfully connected to the database.")
print row
self.status_label.setText("Connected")
else:
print("Connection FAIL")
self.status_label.setText("Disconnected")
def create_connection_window(self):
...rest of the code
...and here is file2
import file1 -> I also tried from file1 import connection_settings_class
class plausible_implausible_class(QtGui.QMainWindow,Ui_plausible_implausible_win):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setupUi(self)
self.show()
sc = MyStaticMplCanvas(self.centralwidget, width=500, height=400, dpi=100)
self.verticalLayout_3.addWidget(sc)
**a = file1.connection_settings_class.cursor_dat**
I might be making a really dumb mistake looking at your sample, but what I see is this:
self.cursor_dat= self.cnxn.cursor()
is defined in the connection_settings_class.connection() method. You never call connection(), so that property never gets created.
Also I noticed that you're calling the class statically, rather than creating an instance of the class but you've created no static properties, they're all created on __init__. You may want to create an instance of your class, which then defines the cursor_dat to be None initially.
If you want connection sharing you can set up a pool of connections and still create individual instances.
Ok, there is not problem with the path because all the scripts that #tdelaney mentioned were positive. The result of for cycle is '/Users/BauchMAC/PycharmProjects/py_GUI/Database_GUI' --> True. And the working directory which I got using os.getcwd() is same.
I also tried to create two new scripts and everything worked. So the problem is that I don't understand to "importing rules" in python because this is the source of the problem.
So there is obviously problem with crossing of imports. And the way to solve it is by passing the value as the parameter.
Below you can see how I wanted to do it and the reason for the error:
file1:
from try4 import ClassB
class ClassA():
def __init__(self):
self.cursor_dat = 1
self.query_selection_win = ClassB()
object1 = ClassA()
file 2:
from try3 import ClassA <-- source of the probles
class ClassB():
def __init__(self, cursor_dat):
print(ClassA.cursor_dat)
And here is how it should be (at least it works, I am not sure if it is the best way how to do it, I am still newbie)
file 1:
from try4 import ClassB
class ClassA():
def __init__(self):
self.cursor_dat = 1
self.query_selection_win = ClassB(self.cursor_dat)
object1 = ClassA()
file 2:
class ClassB():
def __init__(self, cursor_dat):
print(cursor_dat)
I hope it will be helpful to some newbie like me :)
Some environment basics
Python Version: 3.4.2
OS: Windows 8.1
Searching so far, I suspect this other question is related to my issue at hand, but I'm not sure how I'm replicating enough of the same conditions--probably my lack of in-depth python knowledge.
Simplified code to reproduce issue:
Base Class
from PySide.QtGui import *
class Interface(QWidget):
'''
Wrapper base class for GUI input QWidgets:
- buttons
- text fields
- checkboxes
- line edit
- dropdown menu (combo box)
'''
def __init__(self, parent, name, title_txt=None, qt_obj=None,
update_log_method=None):
print('Interface base class constructor has been called.') #DEBUG
self._parent = parent
self.title = None
self.name = name #also text that appears on component
self.qt_obj = qt_obj
self.inheritted_log_method = update_log_method
# don't want to create an empty text QLabel, or one with
# the text reading "None".
if title_txt:
self.title = QLabel(text=title_txt, parent=parent)
print('Interface base class constructor has been completed.') #DEBUG
def get_name(self):
return self.name
def update_log(self, message, level="INFO"):
''' '''
self.inheritted_log_method(message, level)
Inheriting Class
class IFPushButton(Interface):
''' '''
def __init__(self, name, parent, icon=None, update_log_method=None):
''' '''
# print('\n\nCHECKPOINT: pre IFPushButton super()\n\n') #DEBUG
super(IFPushButton, self).__init__(
parent=parent,
name=name,
qt_obj=QPushButton(icon, name, parent),
update_log_method=update_log_method)
self.behaviors = {}
self.qt_obj.clicked.connect(self.activate)
Something to kick it all off
if __name__ == '__main__':
# setup
import sys
app = QApplication(sys.argv)
qmw = QMainWindow()
qcw = QWidget() #central widget
qcl = QVBoxLayout(qcw) #central layout
# experimental
name = 'named button'
ifpb = IFPushButton(name=name, parent=None, icon=None, update_log_method=None)
print("as long a I don't touch the ifpb instance, everything seems to be okay.")
print("...but the second I do...")
qcl.addWidget(ifpb)
self.show()
print("name of created push button:", ifpb.get_name())
# proper teardown
sys.exit(app.exec_())
I run this all inside one module, interface.py, and when I run it...
C:\Path\To\Module> python interface.py
Interface base class constructor has been called.
Interface base class constructor has been completed.
as long a I don't touch the ifpb instance, everything seems to be okay.
...but the second I do...
Traceback (most recent call last):
File "c_interface.py", line 167, in <module>
qcl.addWidget(ifpb)
RuntimeError: '__init__' method of object's base class (IFPushButton) not called.
The part that confuses me is how the print statements in the base class, Intefrace, are obviously being called as they are printing--but it still raises a RuntimeError saying that it hasn't been initialized, and of course fails to get so far as to create the app window. Most of the related messages I've found on stackoverflow are related to people initializing things incorrectly with the super() method--but I have quintuple-checked my super inits, and everything I see tells me it should be working, with the exception of what I linked above.
If I could understand more about why this is happening I'm hoping I can find a way to work around it. Any assistance is much appreciated--thanks in advance!
In the meantime I'm going to try to find how I might be unintentionally deepcopy-ing a C++ object...
EDIT: included the url in the link to other stack overflow post.
Adding a super call to the Interface class constructor is required:
def __init__(self, parent, name, title_txt=None, qt_obj=None, update_log_method=None):
super(Interface, self).__init__(parent)
...
Also, you're calling self.show(), where you probably mean qmw.show().