<div dir="ltr"><div dir="ltr">I'm not able to correctly run your code since I get a network error in the model's loadZone() (I had to add an Exception and obviously return), so I'm not sure about the source of your issue.<div><br>Consider that IDEs often fail to catch all Qt errors and they usually don't display the full traceback, so you should try to run your program from a terminal or prompt in order to (possibly) get more insight about what's happening.</div><div><br></div><div>Also remember that the main UI thread should never be blocked in any way: network requests are potentially blocking and this could create serious issues especially for an item view.</div><div><br></div><div>Maurizio</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il giorno dom 20 giu 2021 alle ore 19:41 Axel Rau <<a href="mailto:Axel.Rau@chaos1.de">Axel.Rau@chaos1.de</a>> ha scritto:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word">Hi, David and Tony,<div><br></div><div>you both are right.</div><div><br></div><div>I made some mistakes while stripping down my codebase and while preparing it for the ML.</div><div>The posted code does not really show the problem, if corrected as you pointed out, Tony, it runs well.</div><div>And yes, I'm using PyCharm as IDE and I have a better structured layout [1].</div><div><br></div><div>To show the problem, I attach new versions of both files.</div><div>The problem happens, if I start creating and loading more zones by calling</div><div>model.loadZones() from the __main__ code in za.py (commented out in the attached version).</div><div>The debugger shows return from model.loadZones(), but nothing is displayed then.</div><div><br></div><div>I guess, model.loadZones() would better be called from some event code, once I’m using events.</div><div><br></div><div>Thanks for your help,</div><div>Axel</div><div><br></div><div>PS: [1] </div></div><div style="word-wrap:break-word"><div></div></div><div style="word-wrap:break-word"><div></div></div><div style="word-wrap:break-word"><div></div><div><br></div><div><br></div><div><div><br><blockquote type="cite"><div>Am 20.06.2021 um 16:01 schrieb Tony Arnold <<a href="mailto:tony.arnold@manchester.ac.uk" target="_blank">tony.arnold@manchester.ac.uk</a>>:</div><br><div><div style="text-align:left;direction:ltr" bgcolor="#ffffff"><div>Hi Alex,</div><div><br></div><div>So the problem is how you reference ZoneModel in za.py. You're referencing it as model.ZoneModel on line 24. You should reference as just ZoneModel.</div><div><br></div><div>You also need to import sys in za.py, but that's not too critical unless you want to pass command line parameters into your application.</div><div><br></div><div>You also need to import QtCore in model.py as someone else has pointed out.</div><div><br></div><div>I've attached the corrected files.</div><div><br></div><div>I highly recommend using a suitable development environment which will highlight syntax and other errors dynamically. I would suggest using eric or pycharm.</div><div><br></div><div>Regards,</div><div>Tony.</div><div><br></div><div>On Sat, 2021-06-19 at 15:25 +0200, Axel Rau wrote:</div><blockquote type="cite" style="margin:0px 0px 0px 0.8ex;border-left:2px solid rgb(114,159,207);padding-left:1ex"><pre>Hi all,</pre><pre><br></pre><pre>I’m new to qt and pyqt.</pre><pre><br></pre><pre>The test app [1] in one module works fine (mainwindow opens and shows loaded data).</pre><pre>After putting ZoneModel and Zone classes in separate modules (za.py, mode.py)[2], no MainWindow is displayed, just the app icon.</pre><pre><br></pre><pre>What am I doing wrong?</pre><pre><br></pre><pre>Any help appreciated,</pre><pre>Axel</pre><pre><br></pre><pre>[1]</pre><pre><br></pre><pre>from za_main_ui import Ui_mainWindow</pre><pre>from PyQt5 import QtWidgets, QtCore</pre><pre><br></pre><pre>##from PyQt5.QtCore import QModelIndex, Qt</pre><pre><br></pre><pre>import dns.query, dns.resolver, dns.zone, dns.rdataset, dns.rdatatype</pre><pre>import sys</pre><pre><br></pre><pre>windowHeading = 'za - DNS zone admin'</pre><pre><br></pre><pre>class ZoneModel(QtCore.QAbstractTableModel):</pre><pre> def __init__(self, data=[[]], parent=None):</pre><pre> super().__init__(parent)</pre><pre> self.zone = Zone('some.do.main‘)</pre><pre><br></pre><pre> def headerData(self, section: int, orientation: QtCore.Qt.Orientation, role: int):</pre><pre> if role == QtCore.Qt.DisplayRole:</pre><pre> if orientation == QtCore.Qt.Horizontal:</pre><pre> return ['OwnerName', 'TTL', 'Type', 'Rdata'][section]</pre><pre> else:</pre><pre> return None</pre><pre><br></pre><pre> def columnCount(self, parent=None):</pre><pre> return self.zone.columnCount()</pre><pre><br></pre><pre> def rowCount(self, parent=None):</pre><pre> return self.zone.rowCount()</pre><pre><br></pre><pre> def data(self, index: QtCore.QModelIndex, role: int):</pre><pre> if role == QtCore.Qt.DisplayRole:</pre><pre> row = index.row()</pre><pre> col = index.column()</pre><pre> return self.zone.data(row, col)</pre><pre><br></pre><pre><br></pre><pre>class Zone(object):</pre><pre> IP_XFR_NS = '1234:5678:9abc:def::1'</pre><pre><br></pre><pre> def __init__(self, zone_name):</pre><pre> self.zone_name = zone_name</pre><pre> self.z = dns.zone</pre><pre> self.d = [['', '', '', '']]</pre><pre><br></pre><pre> def data(self, row: int, column: int) -> str:</pre><pre> if not self.d:</pre><pre> self.loadZone()</pre><pre> v = self.d[row][column]</pre><pre> if not v: v = ''</pre><pre> return str(v)</pre><pre><br></pre><pre> def loadZone(self):</pre><pre> row = 0</pre><pre> self.z = dns.zone.from_xfr(dns.query.xfr(self.IP_XFR_NS, self.zone_name))</pre><pre><br></pre><pre> for name in self.z.keys():</pre><pre> name = str(name)</pre><pre> if name == '@': name = ''</pre><pre> self.d[row][0] = name</pre><pre> node = self.z[name]</pre><pre> for the_rdataset in node:</pre><pre> self.d[row][1] = str(the_rdataset.ttl)</pre><pre> for rdata in the_rdataset:</pre><pre> self.d[row][2] = dns.rdatatype.to_text(the_rdataset.rdtype)</pre><pre> self.d[row][3] = str(rdata)</pre><pre> row = row + 1</pre><pre> self.d.append(['', '', '', ''])</pre><pre><br></pre><pre><br></pre><pre> def columnCount(self):</pre><pre> if len(self.d) < 2:</pre><pre> self.loadZone()</pre><pre> return len(self.d[0])</pre><pre><br></pre><pre> def rowCount(self):</pre><pre> if len(self.d) < 2:</pre><pre> self.loadZone()</pre><pre> return len(self.d)</pre><pre><br></pre><pre><br></pre><pre>class ZaMainWindow(QtWidgets.QMainWindow,Ui_mainWindow):</pre><pre> def __init__(self):</pre><pre> super(ZaMainWindow,self).__init__()</pre><pre> self.setupUi(self)</pre><pre><br></pre><pre>if __name__ == '__main__':</pre><pre> app = QtWidgets.QApplication(sys.argv)</pre><pre><br></pre><pre> domainZones = {}</pre><pre> ip4Zones = {}</pre><pre> ip6Zones = {}</pre><pre><br></pre><pre> subdomains = {}</pre><pre> ip4Nets = {}</pre><pre> ip6Nets = {}</pre><pre><br></pre><pre><br></pre><pre><br></pre><pre> mw = ZaMainWindow()</pre><pre> model = ZoneModel()</pre><pre> view = mw.maintableView</pre><pre> view.setColumnWidth(0, 200)</pre><pre> view.setColumnWidth(1, 40)</pre><pre> view.setColumnWidth(2, 40)</pre><pre> view.setColumnWidth(3, 400)</pre><pre> hh = view.horizontalHeader()</pre><pre> hh.setStretchLastSection(True)</pre><pre> hh.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)</pre><pre> view.setModel(model)</pre><pre> mw.show()</pre><pre><br></pre><pre> sys.exit(app.exec_())</pre><pre><br></pre><pre><br></pre><pre><br></pre><pre>[2]</pre><pre>za.py:</pre><pre><br></pre><pre>from za_main_ui import Ui_mainWindow</pre><pre>from .model import ZoneModel</pre><pre>from PyQt5 import QtWidgets</pre><pre><br></pre><pre><br></pre><pre>class ZaMainWindow(QtWidgets.QMainWindow,Ui_mainWindow):</pre><pre> def __init__(self):</pre><pre> super(ZaMainWindow,self).__init__()</pre><pre> self.setupUi(self)</pre><pre><br></pre><pre>if __name__ == '__main__':</pre><pre> app = QtWidgets.QApplication(sys.argv)</pre><pre><br></pre><pre> domainZones = {}</pre><pre> ip4Zones = {}</pre><pre> ip6Zones = {}</pre><pre><br></pre><pre> subdomains = {}</pre><pre> ip4Nets = {}</pre><pre> ip6Nets = {}</pre><pre><br></pre><pre><br></pre><pre><br></pre><pre> mw = ZaMainWindow()</pre><pre> model = model.ZoneModel()</pre><pre> view = mw.maintableView</pre><pre> view.setColumnWidth(0, 200)</pre><pre> view.setColumnWidth(1, 40)</pre><pre> view.setColumnWidth(2, 40)</pre><pre> view.setColumnWidth(3, 400)</pre><pre> hh = view.horizontalHeader()</pre><pre> hh.setStretchLastSection(True)</pre><pre> hh.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)</pre><pre> view.setModel(model)</pre><pre> mw.show()</pre><pre><br></pre><pre> sys.exit(app.exec_())</pre><pre><br></pre><pre>model.py:</pre><pre><br></pre><pre>import dns.query, dns.resolver, dns.zone, dns.rdataset, dns.rdatatype</pre><pre><br></pre><pre>windowHeading = 'za - DNS zone admin'</pre><pre><br></pre><pre>class ZoneModel(QtCore.QAbstractTableModel):</pre><pre> def __init__(self, data=[[]], parent=None):</pre><pre> super().__init__(parent)</pre><pre> self.zone = Zone('some.do.main')</pre><pre><br></pre><pre> def headerData(self, section: int, orientation: QtCore.Qt.Orientation, role: int):</pre><pre> if role == QtCore.Qt.DisplayRole:</pre><pre> if orientation == QtCore.Qt.Horizontal:</pre><pre> return ['OwnerName', 'TTL', 'Type', 'Rdata'][section]</pre><pre> else:</pre><pre> return None</pre><pre><br></pre><pre> def columnCount(self, parent=None):</pre><pre> return self.zone.columnCount()</pre><pre><br></pre><pre> def rowCount(self, parent=None):</pre><pre> return self.zone.rowCount()</pre><pre><br></pre><pre> def data(self, index: QtCore.QModelIndex, role: int):</pre><pre> if role == QtCore.Qt.DisplayRole:</pre><pre> row = index.row()</pre><pre> col = index.column()</pre><pre> return self.zone.data(row, col)</pre><pre><br></pre><pre><br></pre><pre>class Zone(object):</pre><pre> IP_XFR_NS = '1234:5678:9abc:def::1‘</pre><pre><br></pre><pre> def __init__(self, zone_name):</pre><pre> self.zone_name = zone_name</pre><pre> self.z = dns.zone</pre><pre> self.d = [['', '', '', '']]</pre><pre><br></pre><pre> def data(self, row: int, column: int) -> str:</pre><pre> if not self.d:</pre><pre> self.loadZone()</pre><pre> v = self.d[row][column]</pre><pre> if not v: v = ''</pre><pre> return str(v)</pre><pre><br></pre><pre> def loadZone(self):</pre><pre> row = 0</pre><pre> self.z = dns.zone.from_xfr(dns.query.xfr(self.IP_XFR_NS, self.zone_name))</pre><pre><br></pre><pre> for name in self.z.keys():</pre><pre> name = str(name)</pre><pre> if name == '@': name = ''</pre><pre> self.d[row][0] = name</pre><pre> node = self.z[name]</pre><pre> for the_rdataset in node:</pre><pre> self.d[row][1] = str(the_rdataset.ttl)</pre><pre> for rdata in the_rdataset:</pre><pre> self.d[row][2] = dns.rdatatype.to_text(the_rdataset.rdtype)</pre><pre> self.d[row][3] = str(rdata)</pre><pre> row = row + 1</pre><pre> self.d.append(['', '', '', ''])</pre><pre><br></pre><pre><br></pre><pre> def columnCount(self):</pre><pre> if len(self.d) < 2:</pre><pre> self.loadZone()</pre><pre> return len(self.d[0])</pre><pre><br></pre><pre> def rowCount(self):</pre><pre> if len(self.d) < 2:</pre><pre> self.loadZone()</pre><pre> return len(self.d)</pre><pre><br></pre><pre><br></pre><pre><br></pre><pre>---</pre><pre>PGP-Key: CDE74120 ☀ computing @ chaos claudius</pre><pre><br></pre></blockquote><div><span><pre>-- <br></pre><div><div><font size="2"><font color="#3366ff"><b>Tony Arnold</b> MBCS, CITP | Senior IT Security Analyst | Directorate of IT Services | Office 1, Kilburn Building | The University of Manchester | Manchester M13 9PL | </font><font color="#ff0000">T:</font><font color="#3366ff"> +44 161 275 6093 | </font><font color="#ff0000">M:</font><font color="#3366ff"> +44 773 330 0039</font></font></div></div></span></div></div>
<span id="gmail-m_6619279645011179349cid:4BC4A028-8858-47DA-813F-3EBC8E04BE40@in.chaos1.de"><model.py></span><span id="gmail-m_6619279645011179349cid:E427D8F3-D7ED-462E-BB59-288EC2DB25D2@in.chaos1.de"><za.py></span></div></blockquote></div><br><div>
<div dir="auto" style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none;word-wrap:break-word"><div dir="auto" style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none;word-wrap:break-word"><div style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><div style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><div style="color:rgb(0,0,0);font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><div>---<br>PGP-Key: CDE74120 ☀ computing @ chaos claudius</div></div></div></div></div></div>
</div>
<br></div></div></blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature">È difficile avere una convinzione precisa quando si parla delle ragioni del cuore. - "Sostiene Pereira", Antonio Tabucchi<br><a href="http://www.jidesk.net" target="_blank">http://www.jidesk.net</a></div>